gpt4 book ai didi

swift - 动画更改导航 Controller 中的标题文本

转载 作者:可可西里 更新时间:2023-11-01 01:49:20 25 4
gpt4 key购买 nike

我正在尝试为嵌入在 UINavigationController 中的详细信息 UITableViewController 的标题更改设置动画。

这两个关于堆栈溢出的问答似乎最相关......

我尝试了许多代码变体,主要是根据 Ashley Mills answer 和其他人的回答,但基本上我似乎无法使动画工作!

请注意使用 Xcode 10.2 在 Swift 5 中编写。

我正在使用 Master-Detail UITableViewController 设置来管理列表和该列表中项目的详细信息。

我正在使用大标题...

navigationController?.navigationBar.prefersLargeTitles = true

...和一个搜索 Controller ...

navigationItem.searchController = <<mySearchController>>
navigationItem.hidesSearchBarWhenScrolling = false
definesPresentationContext = true

...所有设置都在主视图 Controller 的 viewDidLoad() 方法中。

这是我所做的。

在我的项目中:

  1. 导入 QuartzCore 框架,根据 Jack Bellis 的评论“您需要通过 [project]>[target]>Build Phases>Link Binaries>QuartzCore.framework 添加 QuartzCore 框架。”;

    在主视图 Controller 中:

  2. 导入QuartzCore;

    在细节 View Controller 中:

  3. viewDidAppear(_ animated: Bool) 方法中,编写类似于上述 OP 答案的 CATransition 代码(这会更改 Large Title ,但没有动画)。

    override func viewDidAppear(_ animated: Bool) {

    super.viewDidAppear(animated)

    let animationTransition = CATransition()

    animationTransition.duration = 2.0

    animationTransition.type = CATransitionType.push
    animationTransition.subtype = CATransitionSubtype.fromTop

    navigationController!.navigationBar.layer.add(animationTransition, forKey: "pushText")

    navigationItem.title = <<NEW TITLE TEXT>>
    }
  4. viewDidAppear(_ animated: Bool) 方法中,编写上述 OP 答案中建议的 CATransition 代码的替代方案(仅添加一个单独的标题到导航栏的中心并且不会改变大标题)。

    override func viewDidAppear(_ animated: Bool) {

    super.viewDidAppear(animated)

    let animationTransition = CATransition()

    animationTransition.duration = 2.0

    animationTransition.type = CATransitionType.fade

    let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 44))
    label.text = <<NEW TITLE TEXT>>
    navigationItem.titleView = label

    navigationItem.titleView!.layer.add(animationTransition, forKey: "fadeText")
    }
  5. 我也试过包括 CAMediaTimingFunction...

        animationTransition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
  6. 我也试过调用 setNeedsLayoutsetNeedsDisplay...

        navigationItem.titleView?.setNeedsLayout()
    navigationController?.navigationBar.setNeedsDisplay()

为清楚起见:

  • 标题文本确实发生了变化,但没有动画;
  • 代码写在viewDidAppear(_ animated:)方法中,因为我想让用户看到转换;
  • 用于测试的持续时间很长(2 秒)- 如果/当动画正常工作时,我可能会减少它;
  • 使用 Storyboard中的检查器,我已经阅读了所有 UITableView/ControllerUINavigationController 设置,看看我是否可以错过了什么。

有什么建议吗?

最佳答案

所以我已经解决了。

我必须在 UINavigationBar 的 subview 中找到包含标题文本的特定层,然后为该层设置动画。结果正是我想要的。

这是我的答案(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

GIF of iOS Simulator illustrating CATransition push fromRight

...这是我确定必须更改的内容的过程...

这个 SO Q&A How to set multi line Large title in navigation bar? ( New feature of iOS 11) 帮助我确定了下面详述的过程,因此特别感谢原始帖子和@Krunal 的 answer

使用相同的代码循环遍历 UINavigationBar 的 subview (如上所述),我使用打印到终端来识别各种 UINavigationItem 及其 subview 。

        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)")

此代码在终端中产生了以下打印结果(对于在模拟器中运行 iOS 12.2 的 iPhone 8 Plus)...

 ____<_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 _UINavigationBarLargeTitleViewUILabel 内的 layer _UINavigationBarContentView。然而,这似乎并不重要,因为当大标题首次出现时,内容 View 中的标签(我假设是当大标题从屏幕上滚动时导航栏中的“旧式”标题)隐藏在 viewDidAppear .

顺便说一句,如果你加入以下两行,你也会有多行大标题:

 largeLabel.numberOfLines = 0
largeLabel.lineBreakMode = .byWordWrapping

但是,我还没有想出如何为大标题框的尺寸增加设置动画,所以立即更改为两行或更多行,恕我直言会破坏标题更改的动画。

尚未在设备上进行测试,但对于 iPhone 和 iPad sims 似乎都可以正常工作。

如果您发现任何错误,请告诉我,我会更新我的答案。

关于swift - 动画更改导航 Controller 中的标题文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55919318/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com