Как победить Excluded Constraints с помощью RubyGem
Но, казалось бы, интерфейс всех контроллеров такой же незамысловатый, как и в релизе полгода назад. Что же случилось? Тем, кто использовал Size Classes, сразу понятно, что интерфейс — не такая простая штука, как кажется. Он ведет себя по-разному в разных ориентациях и на разных дисплеях. Делает он это, потому что некоторые constraints применяются только в определенной ситуации.
Это значит, что в остальных ситуациях эти constraints не используются. У Xcode Interface Builder есть особенность, которая помогает при разработке сложных интерфейсов и мешает при разработке простых. Если добавить constraint к какому-то UIView и затем удалить его из Xcode Inspector (а чаще всего это — самый удобный путь), Xcode не удалит его, а лишь сложит в список неиспользуемых на случай, если понадобится для другого дисплея или ориентации.
Иногда, если развернуть все группы constraints, можно ужаснуться происходящему в storyboard-файле:
Больше половины constraints лежат в «корзине» и ждут, пока их добавят к определенному дисплею или ориентации или удалят. А до тех пор — съедают драгоценные секунды загрузки файла и оставшиеся нервные клетки разработчика.
Что же делать?
Можно открывать по очереди все свои storyboard- и xib-файлы, в них открывать всех наследников UIView и, убедившись, что этот constraint не используется для Size Classes, удалить их, используя Document Outline
А можно предоставить эту скучную, не имеющую права на ошибку работу умному Ruby-скрипту. Итак, нам найти все storyboard- и xib-файлы в проекте:
``` files = Dir.glob("**/*.{storyboard,xib}") files.each{ |file| cleanupConstraints(file)} ```
Готово, теперь в этих файлах надо найти исключенные constraints:
``` require 'nokogiri' def cleanupConstraints(file) f = File.open(file) doc = Nokogiri::XML(f) f.close excluded = doc.xpath('//exclude') end ```
Еще надо не забыть про Size Classes и оставить на местах все constraints, которые включены хоть в одну комбинацию «дисплей/ориентация».
``` require 'nokogiri' def cleanupConstraints(file) f = File.open(file) doc = Nokogiri::XML(f) f.close excluded = doc.xpath('//exclude') included = doc.xpath('//include') result = [] excluded.each do |node| found = false for includedNode in included if node.attr('reference') == includedNode.attr('reference') found = true break end end if !found result.push(node) nodeID = node.attr('reference') constraints = doc.xpath("//constraint[@id='#{nodeID}']") result += constraints end end if result.count > 0 f1 = File.open(file, 'w') result.each{ |node| node.remove } f1.write(doc.to_xml) f1.close p "removed #{result.count} constraint(s) from #{file}" end end ```
Маленькая победа, но как использовать этот скрипт? Ответ прост — создать RubyGem. Для создания Gem есть несколько путей, я использовал описанный здесь guides.rubygems.org/make-your-own-gem. Теперь очистить проект (или даже все проекты разом!) можно, установив Gem
``` $ gem install constraintClean ```
В директории своего проекта (или в директории со всеми своими проектами) выполнив
``` $ constraintClean ```
И это прекрасно!
Комментарии