简体   繁体   English

UITableViewWrapperView 和 UITableView 大小与自动布局不同

[英]UITableViewWrapperView and UITableView size differs with autolayout

I am building a chat.我正在建立一个聊天。 Everything seem to be quite ok but I bumped into sort of 'buggy' problem.一切似乎都很好,但我遇到了某种“越野车”问题。

i got UIViewController with UITextView bar for entering message and UITableView.我得到了带有 UITextView 栏的 UIViewController,用于输入消息和 UITableView。 They are in this constraint: "V:|-(64)-[chatTable][sendMessageBar]-(keyboard)-|"他们在这个约束中: "V:|-(64)-[chatTable][sendMessageBar]-(keyboard)-|" . . When the keyboard is not out - the constant of this constraint is 0 .当键盘未退出时 - 此约束的常量为0 and after keyboard is out - i increase the constant to keyboard height.键盘关闭后 - 我将常数增加到键盘高度。

when the keyboard is not out:键盘未出时:

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)

and when the keyboard comes out:当键盘出来时:

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)

So the UITableViewWrapperView, after I increase constraints constant, differs in size to its superview - UITableView.所以 UITableViewWrapperView,在我增加约束常数之后,大小与其超级视图 - UITableView 不同。 Is there a way to fix this ?有没有办法来解决这个问题 ? I would assume that UITableViewWrapperView would change its frame and bounds according to UITableView but it does not.我会假设UITableViewWrapperView会根据UITableView改变它的框架和边界,但它不会。

Any ideas where is the problem or how could I work around it ?任何想法问题出在哪里或我如何解决它?

ADDING:添加:

After some more research - it seems that it happens somewhere between viewWillLayoutSubviews and viewDidLayoutSubviews .经过更多研究 - 它似乎发生在viewWillLayoutSubviewsviewDidLayoutSubviews之间。 It is kinda weird tho:这有点奇怪:

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

So it seems that something happens there that messes up the UITableViewWrapperView所以似乎那里发生了一些事情,弄乱了UITableViewWrapperView

The following fixed it for me:以下为我修复了它:

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

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    fixTableViewInsets()
}

I discovered that at viewWillAppear() that the insets were all 0. But at viewDidAppear(), they had been modified to apparently offset for navigation bar, etc. This makes the UITableViewWrapperView different from the UITableView.我发现在 viewWillAppear() 处,插图都是 0。但是在 viewDidAppear() 处,它们已被修改为明显偏移导航栏等。这使得 UITableViewWrapperView 与 UITableView 不同。 I changed the insets in its own routine so that it was easier to experiment with calling it from different places.我在自己的例程中更改了插图,以便更容易地尝试从不同的地方调用它。 The viewWillLayoutSubviews() let it get changed before being presented - placing the change in viewDidAppear() caused the table to jerk. viewWillLayoutSubviews() 让它在被呈现之前被改变——将改变放在 viewDidAppear() 中会导致表格抖动。

I ran into this today and while the fix suggested by @anorskdev works nicely, it seems that the root cause of the issue is the automaticallyAdjustsScrollViewInsets property of UIViewController, which is true by default.我今天遇到了这个问题,虽然@anorskdev 建议的修复工作得很好,但问题的根本原因似乎是 UIViewController 的automaticallyAdjustsScrollViewInsets属性,默认情况下为true I turned it off in my storyboard and the problem went away.我在我的故事板中关闭了它,问题就消失了。 Look for the "Adjust Scroll View Insets" checkbox in the View Controller inspector and make sure it's unchecked.在视图控制器检查器中查找“调整滚动视图插入”复选框并确保它未选中。

It seems that it is a bug (fighting with this bug took all day for me) Finally this workaround helped:似乎这是一个错误(与这个错误作斗争对我来说花了一整天时间)最后这个解决方法有帮助:

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);
    }
}

After small investigation I have found this solution with setting all the safeAreaInsets and layoutMargins on the UITableView to zero:经过小调查,我找到了这个解决方案,将UITableView上的所有safeAreaInsetslayoutMargins设置为零:

Swift 4 snipset: Swift 4 片段:

 class CustomTableView: UITableView { override var safeAreaInsets: UIEdgeInsets { get { return .zero } } override var layoutMargins: UIEdgeInsets { get { return .zero } set { super.layoutMargins = .zero } } }

The main problem is safeAreaInsets introduced in tvOS 11.0 - the UITableViewWrapperView just took the properties from the parent view (UITableView) and renders the content with safeAreaInsets.主要问题是tvOS 11.0引入的 safeAreaInsets - UITableViewWrapperView只是从父视图 (UITableView) 获取属性并使用 safeAreaInsets 呈现内容。

I was facing the same issue on tvOS 11.3, and neither of suggestions related with zero insets or scroll disable did the job, except looping through tableView's subviews and setting the UITableViewWrapperView 's frame to the tableView's frame.我在 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)
        }
    }
}

In iOS 11 UITableViewWrapperView has gone, so this problem may occur only on later iOS versions.在 iOS 11 中UITableViewWrapperView已经没有了,所以这个问题可能只会出现在以后的 iOS 版本上。 I faced it on iOS10 when I pushed custom UIViewController in UINavigationController stack.当我在UINavigationController堆栈中推送自定义UIViewController时,我在 iOS10 上遇到了它。

So, the solution is to override property automaticallyAdjustsScrollViewInsets in custom view controller like this:因此,解决方案是在自定义视图控制器中覆盖属性automaticallyAdjustsScrollViewInsets ,如下所示:

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

    }
}

Objective C version of this answer given by anorskdev anorskdev给出的这个答案的目标 C 版本

- (void) viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];
    [tableView setContentInset:UIEdgeInsetsZero];
    [tableView setScrollIndicatorInsets:UIEdgeInsetsZero];
}

edit : Turning off automaticallyAdjustsScrollViewInsets on the hosting ViewController, as suggested by Steve Roy in this answer , also worked and is the one I went with, as it seems cleaner to disable the behaviour rather than correcting it afterwards.编辑:关闭上托管的ViewController automaticallyAdjustsScrollViewInsets,如建议史蒂夫罗伊这个答案,还曾是一个我跟去了,因为它似乎清洁剂禁用行为,而不是事后纠正它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 UITableView子视图不包含UITableViewWrapperView iOS 11 - UITableView subViews does not contain UITableViewWrapperView iOS 11 UITableView的最大大小,同时注意自动布局约束 - UITableView max size while respecting autolayout constraints iOS:AutoLayout UITableView-> UITableViewCell没有显示正确的大小 - IOS: AutoLayout UITableView -> UITableViewCell not showing correct size UITableView + 自动布局 + 固有尺寸:在何处/何时计算尺寸? - UITableView + AutoLayout + Intrinsic Size: Where/when to calculate size? 使用UITableView自动布局 - Autolayout with UITableView 具有AutoLayout的UIScrollView内部的UITableView动态内容大小高度 - UITableView dynamic content size height inside UIScrollView with AutoLayout iOS 11以下无法将类型“ UITableViewWrapperView”的值强制转换为“ UITableView” - Could not cast value of type 'UITableViewWrapperView' to 'UITableView' below iOS 11 什么是自动布局动态大小uitableview单元格的最佳方法 - What is the best approach to autolayout dynamic size uitableview cells 如果行高为 UITableViewAutomaticDimension,则 UITableViewWrapperView 的大小不会根据内容而改变 - UITableViewWrapperView size is not changing as per the content if row height is UITableViewAutomaticDimension UITableView tableHeaderView 以编程方式自动布局 - UITableView tableHeaderView autolayout programmatically
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM