[英]Navigation bar with large titles and right UIBarButtonItem
I am trying to replicate the behaviour shown in Podcasts app (by apple).我正在尝试复制 Podcasts 应用程序(由苹果提供)中显示的行为。
As shown in the image, the rightBarButtonItem
is aligned with the title "Listen Now".如图所示,
rightBarButtonItem
与标题“Listen Now”对齐。 The icon even scrolls up with it (until it disappears).图标甚至会随着它向上滚动(直到它消失)。
The default behavior for a rightBarButtonItem
with large titles it is shown in the library section:带有大标题的
rightBarButtonItem
的默认行为显示在库部分中:
Anyone knows how to replicate the first example?有谁知道如何复制第一个例子? I need a button aligned with the title.
我需要一个与标题对齐的按钮。
Thanks.谢谢。
I don't think they use actual large titles in the podcast app.我不认为他们在播客应用程序中使用真正的大标题。 It looks like they are just using a
tableHeaderView
and making it appear as though it's part of the navigation bar.看起来他们只是在使用
tableHeaderView
并使其看起来好像它是导航栏的一部分。 This works because they erase the shadowImage
of the navigation controllers the navigation bar.这是有效的,因为它们擦除了导航栏导航控制器的
shadowImage
。 Then they place a label with a .largeTitle
sized font in the table header view.然后他们在表格标题视图中放置一个带有
.largeTitle
大小字体的标签。 For example:例如:
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
lazy var titleStackView: TitleStackView = {
let titleStackView = TitleStackView(frame: CGRect(origin: .zero, size: CGSize(width: view.bounds.width, height: 44.0)))
titleStackView.translatesAutoresizingMaskIntoConstraints = false
return titleStackView
}()
lazy var tableHeaderView: UIView = {
let tableHeaderView = UIView(frame: CGRect(origin: .zero, size: CGSize(width: view.bounds.width, height: 44.0)))
tableHeaderView.addSubview(titleStackView)
titleStackView.leadingAnchor.constraint(equalTo: tableHeaderView.leadingAnchor, constant: 16.0).isActive = true
titleStackView.topAnchor.constraint(equalTo: tableHeaderView.topAnchor).isActive = true
titleStackView.trailingAnchor.constraint(equalTo: tableHeaderView.trailingAnchor, constant: -16.0).isActive = true
titleStackView.bottomAnchor.constraint(equalTo: tableHeaderView.bottomAnchor).isActive = true
return tableHeaderView
}()
override func viewDidLoad() {
super.viewDidLoad()
title = nil
navigationController?.navigationBar.isTranslucent = false
navigationController?.navigationBar.barTintColor = UIColor.white
navigationController?.navigationBar.shadowImage = UIImage()
tableView.tableHeaderView = tableHeaderView
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "\(UITableViewCell.self)")
}
}
Where TitleStackView
is a custom view with the UI that you want to appear as the "large title" UI.其中
TitleStackView
是一个自定义视图,其 UI 要显示为“大标题”UI。
For example:例如:
class TitleStackView: UIStackView {
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
private func commonInit() {
axis = .horizontal
alignment = .center
addArrangedSubview(titleLabel)
addArrangedSubview(button)
}
lazy var titleLabel: UILabel = {
let label = UILabel()
label.font = UIFont.systemFont(ofSize: UIFont.preferredFont(forTextStyle: .largeTitle).pointSize, weight: .heavy)
label.text = "Listen Now"
label.setContentHuggingPriority(.defaultLow, for: .horizontal)
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
lazy var button: UIButton = {
let buttonWidth: CGFloat = 35.0
let button = UIButton(frame: CGRect(origin: .zero, size: CGSize(width: buttonWidth, height: buttonWidth)))
button.backgroundColor = .purple
button.setTitleColor(.white, for: .normal)
button.setTitle("B", for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
button.widthAnchor.constraint(equalToConstant: buttonWidth).isActive = true
button.heightAnchor.constraint(equalToConstant: buttonWidth).isActive = true
button.layer.cornerRadius = button.bounds.height * 0.5
button.layer.masksToBounds = true
return button
}()
}
Finally, they use the UIScrollViewDelegate
callback to monitor when to show the title:最后,他们使用
UIScrollViewDelegate
回调来监控何时显示标题:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let maxTitlePoint = tableView.convert(CGPoint(x: titleStackView.titleLabel.bounds.minX, y: titleStackView.titleLabel.bounds.maxY), from: titleStackView.titleLabel)
title = scrollView.contentOffset.y > maxTitlePoint.y ? "Listen Now" : nil
}
If you do all of those things you end up with an effect like the following:如果你做所有这些事情,你最终会得到如下效果:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.