Привет всем!
История началась с того, что мне понадобилось написать приложение под Mac OS X. Все реже можно увидеть статьи по поводу разработок под desktop, да еще и под Mac OS X, но эта тема именно об этом.
Я уже писал много чего на QT, а тут встала задача использовать исключительно Cocoa.
Существует определенная аура святости вокруг продуктов apple, ну и я наивно подпал под нее от моего макбука. Мне казалось что с пользовательским интерфейсом особых проблем не будет, ну разве что какие-то мелочи, которые встречаются везде (ох, как я ошибался).
Вот в проекте я дошел до разработки пользовательского интерфейса и тут мне понадобился классический шаблон Tab View. Продолжение читайте уже под катом.
Предыстория
В общем проект самый обычный в плане пользовательского интерфейса. Пользователь кликает кнопку connect, вводит данные для входа на сервер жмет OK и появляется вкладка для этого сервера и т.д. Войти можно на много серверов и они будут в разных вкладках. Что за сервера и зачем это все нужно это уже другая предметная область не относящаяся к данной статье, поэтому эту информацию я может быть расскажу в другой раз.
Наивный разработчик
Под Mac OS X, да и даже под iOS я еще ни разу не разрабатывал, это мой первый опыт, возможно именно это меня и сделало еще более наивным.
Я думал что тут все проще простого, кину в конструкторе Tab View или как он будет называться в Cocoa в окно, настрою отображение и все, но не тут-то было.
Нахожу в Xcode tab view, кидаю в окно и вижу вот это
Тут уже у меня появились подозрения, что могут возникнуть какие-то сложности.
Ладно подумал я, начал искать другие виджеты для вкладок, их нет. Хорошо, решил разобраться с настройками этого Tab View. Минут 10 повозившись с настройками и поняв, что Tab View к виду вкладок в том же Safari/Finder/Xcode и прочих, его не привести, я отправился на поиски по безграничным просторам интернета.
За первые несколько просмотров постов на stackoverflow.com стало ясно, что Tab View это совсем не то что нужно, я не одинок.
Поиск альтернативного решения
Тут наступил такой момент в разработке когда не пишется ни строчки кода зато читается очень много текста и выпивается очень много кофе.
Вначале я всё-таки попробовал найти что-то от самих Apple, но очень быстро стало ясно что это бесполезно.
Далее я отправился на различные форумы где обсуждалась эта проблема и пути ее решения. Довольно быстро я нашел уже несколько вариантов добавления вкладок в приложения под Mac OS X.
- PSMTabBarControl
- MMTabBarView
- Какие-то примеры можно найти на сайте www.cocoacontrols.com.
- Что-то предлагалось на stackoverflow.com.
Первые два варианта были самыми распространенными и с большим количеством функционала и я решил разбираться с ними.
PSMTabBarControl достачно развитый проект с хорошим функционалом, но уже давно не поддерживается. К слову именно он используется в Adium.
MMTabBarView по сути является продолжением и развитием PSMTabBarControl, но не смотря на это, с поддержкой у его не лучше.
Если взглянуть на его страницу на github, то у него имеется 44 форка, а все это потому что разработчик уже год как не коммитил ничего в master ветку хотя и делал некоторые доработки в develop(но это судя по всему мало кто замечает).
44 форка и среди них несколько активных уходящих от последнего коммита в master и утверждающих что они исправили какие-то баги.
Тут я решил взять тот который активнее других поддерживается.
Был выбран один из форков (как оказалось в последствии совсем не важно какой).
В MMTabBarView есть демо проект который без проблем был откомпилен и работал:
Тут я подумал, что все нормально, форк живой и можно с ним работать.
Я включил фреймворк в сборку своего проекта, сделал все настройки, написал нужный код, запускаю и ничего. Табов нет!
Тупик
Табов нет, ладно, я начал разбираться и выяснил что что-то похожее на табы появляется если я не обновляю Tab View
Если например добавить таб то все пропадает
Вот тут началось веселье. Я начал пробовать все что можно, сначала все разумные средства, а потом уже и не разумные.
- Разные форки. Пришлось перебрать порядка 3-4 форков.
- Настройки. Пробовал разные настройки.
- Я делал новый проект и пробовал все в нем с разными форками.
- На github и в поиске я нашел проекты использующие MMTabBarView и разбирался с ними. Искал отличия с моим кодом.
- Перекапывал форумы в интернете на эту тему.
В общем на многочисленные эксперименты ушел не один день.
В конце у меня было 2 проекта, практически пустых и полностью одинаковых. В одном табы работают, а в другом нет. Встречаясь с таким необъяснимым, наши предки начинали верить в сверхъестественное.
Начали возникать мысли что нужно поискать другую библиотеку.
Эврика или скорее удача
В итоге после долгих поисков непонятной проблемы я решил найти на github максимально простой и маленький проект использующий MMTabBarView и сравнить его с моим.
Был найден какой-то маленький браузер. Из него я убрал все лишнее, и начал сравнивать со своим проектом. Все было идентично. Он так же без проблем работал со сборками MMTabBarView из разных форков.
Дальше возникла идея в этом работающем проекте сделать новое окно и попробовать в нем подключить табы.
И тут победа, табы не заработали. И вот у меня один проект, с одним xib-файлом табы работают с другим нет.
Вывод был очевиден, надо сравнить эти файлы.
Тут работает:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6751" systemVersion="13F1603" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" promptedForUpgradeToXcode5="NO">
Тут не работает:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6751" systemVersion="13F1603" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
В первом же теге я нашел проблему:
customObjectInstantitationMethod="direct"
Если убрать этот атрибут то MMTabBarView начинает корректно работать.
Видимо это связано с тем что отрисовка MMTabBarView ведется как раз в CustomView и этот атрибут как-то на него влияет.
Начинаем разбираться что это такое:
Гугл и яндекс дают кучу ссылок на проиндексированные xib файлы.
Я нашел несколько упоминаний об этом атрибуте, связанных с другими проблема, но для чего он так и не разобрался. Если кто-то знает что это за атрибут и зачем он нужен отпишите, буду очень благодарен.
Заключение
MMTabBarView досточно хороший проект, он поддерживает разное отображение табов, счетчик на табах, добавление иконок, добавление кнопок закрытия и добавление нового таба и многое другое. Жаль только что он размазался по куче форков и непонятно на данный момент как его собрать воедино.
Apple конечно меня огорчил, ну как такое может быть, во всех приложениях элемент пользовательского интерфейса есть, а в библиотеке его нет!?
Самое забавное что табы есть в xcode :)
PS
Вот маленький пример, как подключить MMTabBarView к вашему проекту.
Автор: xanm