Итак, я решил.
Мне нужно было найти определенный слой в подпредставлениях UINavigationBar
, который содержал текст заголовка, а затем анимировать этот слой. Результаты именно то, что я хотел.
Вот мой ответ (Swift 5 iOS 12) ...
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if (newTitle ?? "").isEmpty == false { // only proceed with a valid value for newTitle.
// CATransition code
let titleAnimation = CATransition()
titleAnimation.duration = 0.5
titleAnimation.type = CATransitionType.push
titleAnimation.subtype = CATransitionSubtype.fromRight
titleAnimation.timingFunction = CAMediaTimingFunction.init(name: CAMediaTimingFunctionName.easeInEaseOut)
// this is a detail view controller, so we must grab the reference
// to the parent view controller's navigation controller
// then cycle through until we find the title labels.
if let subviews = parent?.navigationController?.navigationBar.subviews {
for navigationItem in subviews {
for itemSubView in navigationItem.subviews {
if let largeLabel = itemSubView as? UILabel {
largeLabel.layer.add(titleAnimation, forKey: "changeTitle")
}
}
}
}
// finally set the title
navigationItem.title = newTitle
}
Примечание: нет необходимости import QuartzCore
.
... и вот процесс, который я прошел, чтобы определить, что я должен был изменить ...
Это SO Q & A Как установить многострочный большой заголовок на панели навигации? (Новая функция iOS 11)
помог мне определить процесс, подробно описанный ниже, поэтому, в частности, спасибо оригинальному сообщению и ответу @Krunal.
Используя тот же код для циклического просмотра подпредставлений UINavigationBar
(как выше), я использовал распечатку для терминала, чтобы идентифицировать различные UINavigationItem
s и их подпредставления.
counter = 0
if let subviews = parent?.navigationController?.navigationBar.subviews {
for navigationItem in subviews {
print("____\(navigationItem)")
for itemSubView in navigationItem.subviews {
counter += 1
print("_______\(itemSubView)")
}
}
}
print("COUNTER: \(counter)")
этот код дал следующие отпечатки в терминале (для iPhone 8 Plus с iOS 12.2 в симуляторе) ...
____<_UIBarBackground: 0x7f922740c000; frame = (0 -20; 414 116); userInteractionEnabled = NO; layer = <CALayer: 0x6000026ce1c0>>
_______<UIImageView: 0x7f922740c9c0; frame = (0 116; 414 0.333333); userInteractionEnabled = NO; layer = <CALayer: 0x6000026ce7c0>>
_______<UIVisualEffectView: 0x7f922740cbf0; frame = (0 0; 414 116); layer = <CALayer: 0x6000026ce880>>
____<_UINavigationBarLargeTitleView: 0x7f922740f390; frame = (0 44; 414 52); clipsToBounds = YES; layer = <CALayer: 0x6000026cd840>>
_______<UILabel: 0x7f9227499fe0; frame = (20.1667 3.66667; 206.333 40.6667); text = 'Event Details'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x6000005bf250>>
____<_UINavigationBarContentView: 0x7f922740d660; frame = (0 0; 414 44); clipsToBounds = YES; layer = <CALayer: 0x6000026cea00>>
_______<_UIButtonBarStackView: 0x7f92274984a0; frame = (302 0; 100 44); layer = <CALayer: 0x60000261cc60>>
_______<_UIButtonBarButton: 0x7f922749a5c0; frame = (0 0; 82.3333 44); layer = <CALayer: 0x60000261ee60>>
_______<UILabel: 0x7f922749a2d0; frame = (155 11.6667; 104.333 20.3333); text = 'Event Details'; alpha = 0; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x6000005bfc50>>
____<_UINavigationBarModernPromptView: 0x7f9227602db0; frame = (0 0; 0 50); alpha = 0; hidden = YES; layer = <CALayer: 0x6000026e4600>>
COUNTER: 2
Я фактически применил анимацию дважды - к UILabel
layer
в _UINavigationBarLargeTitleView
и UILabel
layer
в _UINavigationBarContentView
. Это, похоже, не имеет значения, потому что, когда впервые появляется большой заголовок, метка в представлении содержимого (что, как я полагаю, относится к заголовку «старого стиля» на панели навигации, когда большой заголовок прокручивается за пределами экрана) скрыта viewDidAppear
.
Кстати, если вы укажете следующие две строки, у вас также будут большие многострочные заголовки:
largeLabel.numberOfLines = 0
largeLabel.lineBreakMode = .byWordWrapping
НО, я еще не выяснил, как анимировать увеличение размера большого титровального кадра, поэтому изменение на две или более строки происходит немедленно, и ИМХО разрушает анимацию изменения заголовка.
Еще не протестировано на устройстве, но, похоже, работает нормально для симов iPhone и iPad.
Если вы найдете какие-либо ошибки, дайте мне знать, и я обновлю свой ответ.