UITableView那些坑


iOS prior to 6.0(included) is not considered. A respondsToSelector check might be needed in terms of compatibility, or exceptions like unrecognized selector sent to instance will occur.

1. eliminate extra separators
   tableView.tableFooterView = [UIView new];

2. eliminate separator insets (iOS8 Only)
    Setting the separatorInset of tableView to UIEdgeInsetsZero is not going to work. It will only effect the extra separators, not the cells that you created.
   iOS8 introduces layoutMargins property on UIView, along with another property called preservesSuperviewLayoutMargins indicating whether superview’s layoutMargins is preserved (Think of it as an override) which is YES by default. layoutMargins property is a set of insets from the edge of the view’s bounds that denote a default spacing for laying out content.
   The default separatorInset of tableView and tableViewCell is (top = 0, left = 15, bottom = 0, right = 0)
   The default layoutMargins of tableView and tableViewCell is(top = 8, left = 8, bottom = 8, right = 8)
   These 3 properties are defining the behaviour of separator indentation.
   However, setting tableView’s layoutMargins is not going to effect tableViewCell. Because tableViewCell’s superview is not tableView. It’s tableView’s subView, an instance of UITableViewWrapperView whose superClass is UIScrollView and whose layoutMargins is (top = 8, left = 15, bottom = 8, right = 15) and preservesSuperviewLayoutMargins is YES.
   You have to set separatorInset and layoutMargins oftableViewCell directly:
    tableViewCell.preservesSuperviewLayoutMargins = NO;
    tableViewCell.separatorInset = UIEdgeInsetsZero;
    tableViewCell.layoutMargins = UIEdgeInsetsZero;
   You can put those code in cell’s init method or awakeFromNib or tableView’s delegate tableView:willDisplayCell:fromRowAtIndexPath, etc.
   Don’t ask me why. I haven’t figured out myself.

3. UIButton-touch-delay in tableViewCell
   When UIButton is added to UITableViewCell as a subview, the highlight state is only activated if you held your finger on the button for more than some fraction of a second. Table view cells are displayed using a UITableView which is a subclass of UIScrollView and as such inherits the ability to scroll. A scroll view intercepts touch events and has a short delay to check if the touch event is part of a scroll gesture. If it isn’t then the touch event is passed onto the corresponding view and the scroll will not be triggered. That explains the delay in the button highlight state.
   We can remove the delay by setting UIScrollView.delaysContentTouches = NO. A side effect of this change is that scroll gesture cannot start from the button. Depending on how big your buttons are this might not be ideal.The work around for this is to override the (BOOL)touchesShouldCancelInContentView:(UIView *)view method in your UITableView subclass like so:
- (BOOL)touchesShouldCancelInContentView:(UIView *)view {
    // Because we set delaysContentTouches = NO, we return YES for UIButtons
    // so that scrolling works correctly when the scroll gesture
    // starts in the UIButtons.

    if ([view isKindOfClass:[UIButton class]]) {
        return YES;
    }

    return [super touchesShouldCancelInContentView:view];
}
   However, this is not enough for iOS 8 as the UITableViewCell has a build-in subview called UITableViewCellScrollView which is a subclass of UIScrollView. That means three are more than one UIScrollView in the button’s superviews. So besides setting UITableView’s delayContentTouches, you have to set UITableViewCell too.
    for (id currentView in tableViewCell.subviews) {
        if ([NSStringFromClass([currentView class]) isEqualToString:@"UITableViewCellScrollView"]) {
            if ([currentView isKindOfClass:[UIScrollView class]]) {
                [(UIScrollView *)currentView setDelaysContentTouches:NO];
            }
        }
    }

4. UITableViewCell changes all its subviews’ background color when selected
   The problem is like this: Put a UIButton onto UITableViewCell as a subview of UITableViewCell.contentView first. And when the cell is selected the button’s background becomes transparent. This feature that UITableViewCell changes the backgroundColor of all subviews on selection to clearColor is weird. What the system does under the hood is:

Set all its subviews' backgroundColor to clear color(transparent).
Highlight all subviews that can be highlighted(UIControl excluded), for example, UIImageView.

   If it’s UIButton that you really care about, the solution is simple: Set UIButton’s backgroundImage of normal state instead of backgroundColor. If not, the solution is may not be that comfortable. There are still 3 options:
   1. If your view’s backgroundColor has no change to be clearColor, you can subclass the view and override setBackgroundColor: and check if the parameter is clearColor, and do nothing if YES.
   2. You can override setBackgroundColor and do nothing in it. And add your own property, say MyOwnBackgroundColor, and use it to set the backgroundColor (call [super setBackgroundColor:]).
   3. override these two methods in your UITableViewCell subclass:

- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
    [super setHighlighted:highlighted animated:animated];
    if (highlighted) {
        // Recover backgroundColor of subviews.
    }
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
    if (selected) {
        // Recover backgroundColor of subviews.
    }
}



龙西村原创, 转载请注明出处.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值