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
After small investigation I have found this solution with setting all the safeAreaInsets
and layoutMargins
on the UITableView
to zero:
Swift 4 snipset:
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.
Objective C version of this answer given by anorskdev
- (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.
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. 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.
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);
}
}
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.
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. I faced it on iOS10 when I pushed custom UIViewController
in UINavigationController
stack.
So, the solution is to override property automaticallyAdjustsScrollViewInsets
in custom view controller like this:
override var automaticallyAdjustsScrollViewInsets: Bool {
get {
return false
}
set {
}
}