Весёлые табы в MAC OS X или история про тот самый Tab View

в 20:01, , рубрики: Cocoa, mac os x, tab view, user interfaces, разработка, Разработка под OS X, метки:

Привет всем!

История началась с того, что мне понадобилось написать приложение под Mac OS X. Все реже можно увидеть статьи по поводу разработок под desktop, да еще и под Mac OS X, но эта тема именно об этом.

Я уже писал много чего на QT, а тут встала задача использовать исключительно Cocoa.

Существует определенная аура святости вокруг продуктов apple, ну и я наивно подпал под нее от моего макбука. Мне казалось что с пользовательским интерфейсом особых проблем не будет, ну разве что какие-то мелочи, которые встречаются везде (ох, как я ошибался).

Вот в проекте я дошел до разработки пользовательского интерфейса и тут мне понадобился классический шаблон Tab View. Продолжение читайте уже под катом.

Предыстория

В общем проект самый обычный в плане пользовательского интерфейса. Пользователь кликает кнопку connect, вводит данные для входа на сервер жмет OK и появляется вкладка для этого сервера и т.д. Войти можно на много серверов и они будут в разных вкладках. Что за сервера и зачем это все нужно это уже другая предметная область не относящаяся к данной статье, поэтому эту информацию я может быть расскажу в другой раз.

Наивный разработчик

Под Mac OS X, да и даже под iOS я еще ни разу не разрабатывал, это мой первый опыт, возможно именно это меня и сделало еще более наивным.
Я думал что тут все проще простого, кину в конструкторе Tab View или как он будет называться в Cocoa в окно, настрою отображение и все, но не тут-то было.

Нахожу в Xcode tab view, кидаю в окно и вижу вот это
Весёлые табы в MAC OS X или история про тот самый Tab View - 1

Тут уже у меня появились подозрения, что могут возникнуть какие-то сложности.

Ладно подумал я, начал искать другие виджеты для вкладок, их нет. Хорошо, решил разобраться с настройками этого Tab View. Минут 10 повозившись с настройками и поняв, что Tab View к виду вкладок в том же Safari/Finder/Xcode и прочих, его не привести, я отправился на поиски по безграничным просторам интернета.

За первые несколько просмотров постов на stackoverflow.com стало ясно, что Tab View это совсем не то что нужно, я не одинок.

Поиск альтернативного решения

Тут наступил такой момент в разработке когда не пишется ни строчки кода зато читается очень много текста и выпивается очень много кофе.
Вначале я всё-таки попробовал найти что-то от самих Apple, но очень быстро стало ясно что это бесполезно.
Далее я отправился на различные форумы где обсуждалась эта проблема и пути ее решения. Довольно быстро я нашел уже несколько вариантов добавления вкладок в приложения под Mac OS X.

Первые два варианта были самыми распространенными и с большим количеством функционала и я решил разбираться с ними.
PSMTabBarControl достачно развитый проект с хорошим функционалом, но уже давно не поддерживается. К слову именно он используется в Adium.
MMTabBarView по сути является продолжением и развитием PSMTabBarControl, но не смотря на это, с поддержкой у его не лучше.
Если взглянуть на его страницу на github, то у него имеется 44 форка, а все это потому что разработчик уже год как не коммитил ничего в master ветку хотя и делал некоторые доработки в develop(но это судя по всему мало кто замечает).
44 форка и среди них несколько активных уходящих от последнего коммита в master и утверждающих что они исправили какие-то баги.
Тут я решил взять тот который активнее других поддерживается.

Был выбран один из форков (как оказалось в последствии совсем не важно какой).

В MMTabBarView есть демо проект который без проблем был откомпилен и работал:

Весёлые табы в MAC OS X или история про тот самый Tab View - 2

Тут я подумал, что все нормально, форк живой и можно с ним работать.
Я включил фреймворк в сборку своего проекта, сделал все настройки, написал нужный код, запускаю и ничего. Табов нет!

Тупик

Табов нет, ладно, я начал разбираться и выяснил что что-то похожее на табы появляется если я не обновляю Tab View

Весёлые табы в MAC OS X или история про тот самый Tab View - 3

Если например добавить таб то все пропадает

Весёлые табы в MAC OS X или история про тот самый Tab View - 4

Вот тут началось веселье. Я начал пробовать все что можно, сначала все разумные средства, а потом уже и не разумные.

  • Разные форки. Пришлось перебрать порядка 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 и этот атрибут как-то на него влияет.

Начинаем разбираться что это такое:
Весёлые табы в MAC OS X или история про тот самый Tab View - 5
Гугл и яндекс дают кучу ссылок на проиндексированные xib файлы.

Я нашел несколько упоминаний об этом атрибуте, связанных с другими проблема, но для чего он так и не разобрался. Если кто-то знает что это за атрибут и зачем он нужен отпишите, буду очень благодарен.

Заключение

MMTabBarView досточно хороший проект, он поддерживает разное отображение табов, счетчик на табах, добавление иконок, добавление кнопок закрытия и добавление нового таба и многое другое. Жаль только что он размазался по куче форков и непонятно на данный момент как его собрать воедино.
Apple конечно меня огорчил, ну как такое может быть, во всех приложениях элемент пользовательского интерфейса есть, а в библиотеке его нет!?
Самое забавное что табы есть в xcode :)

PS
Вот маленький пример, как подключить MMTabBarView к вашему проекту.

Автор: xanm

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js