iOS 11首选滚动

时间:2017-06-09 02:00:33

标签: ios swift cocoa-touch uinavigationcontroller uikit

我实现了一个带有UITableView的基本UIViewController,它包含在UINavigationController中。我将prefersLargeTitles设置为true:

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    navigationController?.navigationBar.prefersLargeTitles = true
    navigationItem.title = "Coffees"
}

然而,标题一直很小,直到我滚动视图,此时它会放大。我尝试将该调用移动到我创建UINavigationController的位置,但没有效果。我确定当我设置prefersLargeTitles时,navigationController不是nil。

我应该在其他地方更新该物业吗?或者我应该提交雷达?

更新

如果我的观点包含UITableView或其本身为UITableViewController

,则似乎只会发生这种情况

26 个答案:

答案 0 :(得分:19)

我遇到了同样的问题。虽然你没有使用故事板,但我希望这可以帮助某人。我检查了#34;喜欢大标题"对于导航控制器(不是视图控制器)我嵌入了我的TableViewController。导航控制器转向后所有的视图控制器都有大标题,它应该可以工作。

答案 1 :(得分:8)

我只在一个tableview上遇到同样的问题...

我必须设置:

self.tableView.contentInsetAdjustmentBehavior = .never

以便在加载uiviewcontroller时我的tableview停止滚动。

这是tableview自动滚动,使大标题隐藏

希望这有帮助

答案 2 :(得分:4)

使用top:1修改tableView的contentInset将强制NavigationBar展开并显示大标题。

的OBJ-C

-(void) viewWillAppear:(BOOL)animated {
    if (@available(iOS 11.0, *)) {
        tableView.contentInset = UIEdgeInsetsMake(1, 0, 0, 0);
    }
}

夫特

override func viewWillAppear(_ animated: Bool) {
    if #available(iOS 11.0, *) {
        tableView.contentInset = UIEdgeInsetsMake(1, 0, 0, 0)
    }
}

注意:如果tableView.reloadData()中有viewWillAppear,请务必在修改contentInset

后调用它

答案 3 :(得分:3)

与Swift 5.2相同的问题

我的视图包含tableView,而preferredLargeTitles直到滚动才更新,我通过设置

对其进行了修复

enter image description here

self.tableView.contentInsetAdjustmentBehavior = .never

答案 4 :(得分:3)

我最近遇到了同样的问题,没有任何建议对我有用。相反,我要做的就是调用sizeToFit()。示例代码:

private func configureNavigator() {
    guard let navigationController = navigationController else { return }
    navigationController.navigationBar.prefersLargeTitles = true
    navigationItem.largeTitleDisplayMode = .automatic
    navigationController.navigationBar.sizeToFit()
}

我希望这会有所帮助!

答案 5 :(得分:1)

常规更改navigationBar的行为应在viewWillAppear(_:)

中完成
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.navigationController?.navigationBar.prefersLargeTitles = true
}

这样做之后对我来说很好。

答案 6 :(得分:1)

对我来说,唯一可行的解​​决方案是:

stats = 'T'

DispatchQueue.main.async { [weak self] in
    self?.navigationController?.navigationBar.sizeToFit()
}

答案 7 :(得分:1)

我认为这似乎有点虚构,但我有效地解决了这个问题:

self.navigationItem.prompt = ""

self.navigationItem.prompt = nil

就像navigationBar需要在其中一个元素中进行某种更新以更新布局一样。

有时要更新NavigationBar中的某些内容,我需要隐藏和取消隐藏它。这就是为什么我认为有最佳方法可以这样做。.目前,这是我的解决方法。

答案 8 :(得分:1)

以编程方式:

  1. 在AppDelegate.swift中:

    window = UIWindow(frame: UIScreen.main.bounds)
    window?.makeKeyAndVisible()
    
    let navigationController = UINavigationController.init(rootViewController: ViewController())
    window?.rootViewController = navigationController
    
  2. 在ViewController中:

    覆盖func viewWillAppear(_动画:Bool){     super.viewWillAppear(动画)

    navigationController?.navigationBar.prefersLargeTitles = true
    navigationItem.largeTitleDisplayMode = .automatic
    

    }

    覆盖func loadView(){     super.loadView()

    view.addSubview(tableView)
    view.addSubview(loadingView)
    
    NSLayoutConstraint.activate([
        tableView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
        tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
        tableView.widthAnchor.constraint(equalTo: view.safeAreaLayoutGuide.widthAnchor),
        tableView.heightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.heightAnchor)
        ])
    

    }

确保您的表视图已首先添加到视图中!

答案 9 :(得分:1)

我通过情节提要解决了这个问题

  1. 导航控制器->导航栏->属性检查器->偏好大标题(已选中)
  2. 视图控制器->导航项->属性检查器->大标题(自动或始终选中)

答案 10 :(得分:1)

我浪费了相当多的时间,因为prefersLargeTitle saga在某些视图控制器上按预期工作,有些它会产生同样的问题。

我的解决方案是取消选中IB中顶栏下的扩展边缘 - 对于那些暂时显示大标题的视图控制器,直到加载了表格视图的内容,导航栏才会跳回到常规大小。它只在向下滚动表格视图时显示大标题。

这与iOS 10向后兼容,并且不会在表格视图的第一行上方留下任何空白区域。

我只在IB中检查了导航控制器属性检查器上的prefersLargeTitle - 代码中没有任何内容。 largeTitleDisplayMode = .always

也是如此

至于为什么一些视图控制器而不是其他视图控制器发生这种情况,我完全不知道!

答案 11 :(得分:1)

在我的情况下,解决方案是将tableView的顶部对齐设置为安全区而不是Superview

答案 12 :(得分:1)

我遇到了同样的问题,发现通常最好从视图控制器或设置它的对象设置prefersLargeTitles属性,并在呈现之前这样做。

例如,如果在应用启动时显示有问题的视图控制器:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    let window = UIWindow(frame: UIScreen.main.bounds)

    let someViewController: UIViewController = CustomViewController()

    let theNavController = UINavigationController(rootViewController: someViewController)
    theNavController.navigationBar.prefersLargeTitles = true

    window.rootViewController = theNavController
    window.makeKeyAndVisible()

    return true
}

或者如果呈现特定的视图控制器:

let someViewController: UIViewController = CustomViewController()

let theNavController = UINavigationController(rootViewController: someViewController)
theNavController.navigationBar.prefersLargeTitles = true

present(theNavController, animated: true, completion: nil)

我发现这种方法是一种更加可靠的方法,可以确保相应地显示导航标题。希望这可以帮助! :)

答案 13 :(得分:1)

我刚刚遇到了同样的问题,在我的情况下,事实证明,在iOS 10中使用Swift 3工作的Storyboard结构(以及适用于iOS 11和Swift 3的)在iOS 11上引发了问题斯威夫特4。

详细说明:

我的故事板中有一个常规的UIViewController我已经设置为UINavigationController子类(我的层次结构类似于你的,UITabBarController子类→UINavigationController子类→UITableViewController子类)。

在iOS 10中,这很好用。

在iOS 11中,当您运行现有的Swift 3应用程序时,这也可以正常工作。

然而,使用在iOS 11上运行的Swift 4应用程序,我看到了您描述的相同症状(只有当您向下拉/向下滚动视图时才会显示大标题。)

要修复,我用实际的UINavigationController实例替换了故事板中基于UIViewController的元素(在Storyboard中显式包含UINavigationBar - 我有一个预感,这是问题的关键所在,因为UIViewController实例没有在故事板中明确声明了该元素。

无论如何,这为我解决了这个问题。

我将提交雷达,因为这看起来像是基于Swift 4的回归,对我来说,它适用于iOS 10和Swift 3以及iOS 11和Swift 3。

答案 14 :(得分:1)

在故事板中,我将导航项Large Title设置为Never

Navigation Item

在我的ViewController的viewDidLoad方法中,我设置了以下内容:

navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.largeTitleDisplayMode = .always

答案 15 :(得分:0)

我尝试了所有其他答案,但对我有用的是将 UITableView 的内容偏移量设置为 CGPoint(x: 0, y: -1) 中的 viewDidLoad

tableView.setContentOffset(CGPoint(x: 0, y: -1), animated: false)

答案 16 :(得分:0)

我遇到了同样的问题。

我在 viewdidload 方法中设置了以下代码。并得到修复。

self.navigationController?.navigationBar.prefersLargeTitles = true

self.navigationItem.largeTitleDisplayMode = .never

答案 17 :(得分:0)

我遇到了同样的问题(iOS 14,Xcode 12.2)。

它只影响显示表格视图的导航控制器。

我最初将tableView.tableFooterView = UIView()设置为摆脱最后一个单元格之后的多余分隔符。 将页脚视图设置为nil可以修复滚动的导航标题。

答案 18 :(得分:0)

对我有用的是在调用tableviews reload方法之前设置M

答案 19 :(得分:0)

一开始看起来确实是一种奇怪的行为,但请尝试将navigationItem.largeTitleDisplayMode设置为always。默认值为automatic - 并且未定义docs中的工作方式。

还写了/将更新有关大片here的答案。

答案 20 :(得分:0)

导航栏也有类似的问题,但是在我的情况下,导航栏有一个自定义标题视图,导航栏一直为空,直到向下滚动表视图为止,这触发了UILayoutContainerView布局其子视图,其中一个子视图是导航控制器的视图和导航栏。我认为其根源与大标题导航栏问题相同。

tableView固定在safeAreaLayoutGuide上对我来说不起作用,largeTitleDisplayMode不可能不是.never

因此,我设法通过在顶部提供的控制器的self.navigationController?.view.setNeedsUpdateConstraints函数中调用viewDidAppear(animated:)来解决此问题,或者将该调用调度到viewWillAppear(animated:)中的下一个运行循环中,例如:

DispatchQueue.main.async {
    self.navigationController?.view.setNeedsUpdateConstraints()
}

在这种情况下,导航栏会显示正确的内容和大小以及当前的过渡效果,而不是在过渡完成后弹出

答案 21 :(得分:0)

与Swift 4.2,iOS 12和重构的Storyboard相同。

试图将prefersLargeTitles = true添加到viewWillAppearviewDidLoad,但都没有解决我的问题。

相反,我将重构的故事板复制回main.storyboard中,并找到了在IB中启用大标题的选项。设置该选项,然后重新构建情节提要,一切都可以正常工作了。由于某种原因,最初的重构去除了该选项,而我无法以编程方式启用它。

答案 22 :(得分:0)

另一种可能的解决方案是在refreshHandler()中结束刷新。像这样-

@objc func refreshPage() {
    self.refreshControl?.endRefreshing() //End here
    self.loadTableData() //Get fresh data and reload table
}

答案 23 :(得分:0)

对我来说,类似的问题是在UITableViewController中添加了UIViewController。在我的实例中,这些视图控制器本身嵌入在UITabBarController中,并且只有正确显示的第一个选项卡使用大标题。其他选项卡需要手动滚动才能显示大标题。

我唯一可以做的就是按照@ pau-senabre的回答调整contentInset,除了top插图对我没有帮助。相反,我设置了left插入,然后在下一个运行循环中将其重置。

private var isFirstAppearance = true

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    if isFirstAppearance {
        applyLargeTitlesFix()
    }
}

private func applyLargeTitlesFix() {
    let originalInset = tableViewController.tableView.contentInset
    tableViewController.tableView.contentInset = UIEdgeInsets(top: 0, left: 1, bottom: 0, right: 0)
    DispatchQueue.main.async { [weak self] in
        self?.tableViewController.tableView.contentInset = originalInset
    }
    isFirstAppearance = false
}

答案 24 :(得分:0)

我遇到了同样的问题,并通过在InterfaceBuilder中更改ViewController中的视图顺序来修复它。

似乎Hierarchy中的第一个视图不是ScrollView,然后NavigationBar以LargeTitle模式显示,并且不与滚动视图一起动画。如果需要导航栏标题以反映滚动,则需要将滚动视图作为视图层次结构中的第一个。

此外,我对此并不完全确定,但看起来标准或大标题模式下的导航栏外观取决于以前Controller的视图层次结构。

答案 25 :(得分:0)

我有类似的问题。视图是表格视图。 prefersLargeTitles的属性设置为viewDidLoad事件。然后我在viewWillAppear事件中设置了视图标题。

override open func viewDidLoad() {
   if #available(iOS 11.0, *) {
        self.navigationController?.navigationBar.prefersLargeTitles = true
    } else {
        // Fallback on earlier versions
    }
    ...
}

override open func viewWillAppear(_ animated: Bool) {
    self.navigationItem.title = "something"
    ...
}

在我的准备segue事件中,我将导航项目的磁贴设置为nil,以便下一个视图左侧导航变量项目显示"返回"自动。

override func prepare(for segue: UIStoryboardSegue,
                      sender: Any?) {
    self.navigationItem.title = nil
    ...
}

表格视图第一次正确显示大标题。但是,如果我选择一行到下一个视图并返回到表视图,则导航项的标题将变为空。

几个小时后'挣扎,我终于发现视图的标题应该在viewDidAppear事件中设置!似乎在Will事件中设置查看标题的任何内容都将被UIKit内部重置为零。所以它必须设置在不同的事件中。

override func viewDidAppear(_ animated: Bool) {
   self.navigationItem.title = "something"
   ...
}

override open func viewWillAppear(_ animated: Bool) {
    // self.navigationItem.title = "something" // Remove it and set title in Did event!
    ...
}

在我介绍这个iOS 11新功能之前,我的应用运行正常。似乎新功能在UIKit中有一些变化,因此以前的版本应用可能需要一些更新/更改才能使其正常工作。