我有一个嵌入了导航控制器的视图控制器,且使用了大标题选项;在视图控制器内部有一个滚动视图。
我想要在滚动时使导航栏收缩。
如何实现这一目标?
Xcode 9、Swift 4、iOS 11
class P1ViewController: UIViewController, UIScrollViewDelegate
{
var canTransitionToLarge = false
var canTransitionToSmall = true
func scrollViewDidScroll(_ scrollView: UIScrollView)
{
if canTransitionToLarge && scrollView.contentOffset.y <= 0 {
UIView.animate(withDuration: 0.5) {
self.navigationItem.largeTitleDisplayMode = .always
}
canTransitionToLarge = false
canTransitionToSmall = true
}
else if canTransitionToSmall && scrollView.contentOffset.y > 0 {
UIView.animate(withDuration: 0.5) {
self.navigationItem.largeTitleDisplayMode = .never
}
canTransitionToLarge = true
canTransitionToSmall = false
}
}
}
UITableViewController
嵌套在UINavigationController
中。这使我能够同时:(1)显示UINavigationBar
和(2)使用navigationController?.navigationBar.prefersLargeTitles = true
显示大标题(自动调整滚动手势)。 - Andrew KirnaUIViewController
,其中包含一个嵌套的 UINavigationBar
和用于滚动内容的 UITextView
,那么您应该考虑使用额外的 UIScrollViewDelegate
方法,例如 scrollViewWillBeginDragging(_:)
、scrollViewDidScroll(_:)
和 scrollViewDidScrollToTop(_:)
来更频繁地更新 largeTitleDisplayMode
。请记住,UITextViewDelegate
继承自 UIScrollViewDelegate
,因此您可以访问所有这些超类方法。请记得在 viewDidLoad()
中使用从 UITextView
的 outlet 设置视图控制器中的委托,如 textView.delegate = self
。 - Andrew Kirna我曾经遇到过类似的问题,原因是在视图控制器中有许多基于UIScrollView
的视图,并且我没有首先滚动层次结构。一旦只有一个UIScrollView
,WKWebView
或UITextView
,它们就可以正常工作,而不需要任何代码。
因此,我必须设置UIWebView ScrollView代理:
self.webView.scrollView.delegate = self
并且
extension MyViewController: UIScrollViewDelegate {
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
if #available(iOS 11.0, *) {
UIView.animate(withDuration: 0.5, animations: {
self.navigationController?.navigationBar.prefersLargeTitles = (velocity.y < 0)
})
}
}
}
我在使用类似于Kamil Szostakowski的答案来处理包含UICollectionView的视图。
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
UIView.animate(withDuration: 0.5, animations: {
self.navigationController?.navigationBar.prefersLargeTitles = (velocity.y < 0)
})
}
我使用故事板方法进行了测试,它可以正常工作。 请确保设置scrollView及其子视图的约束条件。
这里提供测试样例XCode项目以供参考:https://github.com/DazChong/LargeTitleShrinkOnScrollView
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if #available(iOS 11.0, *) {
let offset = scrollView.contentOffset
rootVC.scrollView.contentOffset = offset
}
}
UIView
动画和撤消更大的标题之前,请先检查此链接。 - Mathi Arasan