UITableViewWrapperView和UITableView大小因自动布局而异

我正在聊天。 一切似乎都很好,但我碰到了一些“越野车”的问题。

我得到UIViewController与UITextView栏输入消息和UITableView。 他们处于这种约束: "V:|-(64)-[chatTable][sendMessageBar]-(keyboard)-|" 。 键盘未输出时 – 此约束的常量为0 。 键盘输出后 – 我将常量增加到键盘高度。

键盘没出时:

 self.table.contentSize = (375.0,78.5) self.table.bounds = (0.0,-490.0,375.0,568.5) self.table.frame = (0.0,64.0,375.0,568.5) self.table.subviews[0].frame (UITableViewWrapperView) = (0.0,0.0,375.0,568.5) self.table.subviews[0].frame (UITableViewWrapperView) = (0.0,0.0,375.0,568.5) 

当键盘出现时:

 self.table.contentSize = (375.0,78.5) self.table.bounds = (0.0,-274.0,375.0,352.5 self.table.frame = (0.0,64.0,375.0,352.5) self.table.subviews[0].frame (UITableViewWrapperView) = (0.0,-137.5,375.0,137.5) self.table.subviews[0].frame (UITableViewWrapperView) = (0.0,0.0,375.0,137.5) 

因此,在我增加约束常量之后,UITableViewWrapperView的大小与其superview – UITableView不同。 有没有办法来解决这个问题 ? 我会假设UITableViewWrapperView会根据UITableView更改其框架和边界,但事实并非如此。

任何想法在哪里是问题或我如何解决它?

并补充说:

经过一些更多的研究 – 它似乎发生在viewWillLayoutSubviewsviewDidLayoutSubviews之间。 这有点奇怪:

 override func viewWillLayoutSubviews() { println("WrapperView Frame :991: \(self.table.subviews[0].frame)") \\ WrapperView Frame :991: (0.0,0.0,375.0,568.5) super.viewWillLayoutSubviews() println("WrapperView Frame :992: \(self.table.subviews[0].frame)") \\ WrapperView Frame :992: (0.0,0.0,375.0,568.5) } override func viewDidLayoutSubviews() { println("WrapperView Frame :6: \(self.table.subviews[0].frame)") \\ WrapperView Frame :6: (0.0,-137.5,375.0,137.5) super.viewDidLayoutSubviews() println(">> viewDidLayoutSubviews") } 

所以似乎那里发生的事情弄乱了UITableViewWrapperView

以下为我修好了:

 func fixTableViewInsets() { let zContentInsets = UIEdgeInsetsZero tableView.contentInset = zContentInsets tableView.scrollIndicatorInsets = zContentInsets } override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() fixTableViewInsets() } 

我发现在viewWillAppear()中,insets都是0.但是在viewDidAppear()中,它们被修改为显然偏移了导航栏等。这使得UITableViewWrapperView与UITableView不同。 我在自己的例程中更改了insets,以便更容易尝试从不同的地方调用它。 viewWillLayoutSubviews()让它在呈现之前被更改 – 将更改放在viewDidAppear()中会导致表格抖动。

它似乎是一个bug(与这个bug争夺一整天对我来说)最后这个解决方法帮助:

 for (UIView *subview in tableView.subviews) { if ([NSStringFromClass([subview class]) isEqualToString:@"UITableViewWrapperView"]) { subview.frame = CGRectMake(0, 0, tableView.bounds.size.width, tableView.bounds.size.height); } } 

今天我遇到了这个问题,虽然@anorskdev建议的修复工作很好,但问题的根本原因似乎是UIViewController的automatedAdjustsScrollViewInsets属性,默认情况下为true 。 我在故事板中将其关闭,问题就消失了。 在View Controller检查器中查找“调整滚动视图插入”复选框,并确保未选中它。

在iOS 11中, UITableViewWrapperView已经消失,因此仅在以后的iOS版本上可能会出现此问题。 当我在UINavigationController堆栈中推送自定义UIViewController时,我在iOS10上遇到了它。

所以,解决方案是在自定义视图控制器中automaticallyAdjustsScrollViewInsets覆盖属性,如下所示:

 override var automaticallyAdjustsScrollViewInsets: Bool { get { return false } set { } } 

我在tvOS 11.3上遇到了同样的问题,除了通过tableView的子视图循环并将UITableViewWrapperView的框架设置为tableView的框架之外,与零插入或滚动禁用相关的建议都没有完成。

  override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) for view in tableView.subviews { if String(describing: type(of: view)) == "UITableViewWrapperView" { view.frame = CGRect(x: 0, y: 0, width: tableView.bounds.size.width, height: tableView.bounds.size.height) } } }