在 Swift 中消除 UITableView 中空行的额外分隔线

Eliminating extra separator lines for empty rows in UITableView in Swift

在使用代码删除表视图中的额外分隔线时,我在 viewcontroller 中为表视图创建了一个出口,然后设置

self.tableview.tableFooterView = UIView()

在检查 class UIView 时,默认初始化程序有框架参数,

class UIView : UIResponder, NSCoding, UIAppearance, NSObjectProtocol, UIAppearanceContainer, UIDynamicItem, UITraitEnvironment, UICoordinateSpace {

    class func layerClass() -> AnyClass // default is [CALayer class]. Used when creating the underlying layer for the view.
    init(frame: CGRect) // default initializer
    var userInteractionEnabled: Bool // default is YES. if set to NO, user events (touch, keys) are ignored and removed from the event queue.
    var tag: Int // default is 0
    var layer: CALayer { get } // returns view's layer. Will always return a non-nil value. view is layer's delegate
}

正在使用,

self.tableview.tableFooterView = UIView(frame: CGRectZero)

也有效。当 UIView class 中的默认初始值设定项不同时(它确实继承自许多其他 classes),为什么第一种方法有效并且不报错?删除分隔符的两条线有何不同(如果它们不同),哪一条更有效并且应该使用?

UIViewNSObject 继承了 init(),这就是为什么它是有效的并且不会给出任何错误。 Cocoa(Touch) 中与 Objective-C 一起使用的每个 class 都继承自此 class(也许 NSProxy 除外)。很明显,UIViewframe 属性 默认为 CGRectZero,这就是它仍然有效的原因。

我会说你总是选择 init(frame:),因为它是 Designated Initializer for UIView。它为 reader 提供了更清晰的意图。 通过使用 init(),您无法确定所有属性的设置是否比使用 init(frame:) 更正确。

更新

做了一些小实验后,我发现 UIView.init() 通过传递 CGRectZero 来调用 UIView.init(frame:)。所以,我会说两者 完全等价 。但是,我仍然建议您使用 init(frame:),因为它可以表达比 reader 更清晰的意图。但这取决于你的风格。

代码如下:

@interface MyView : UIView

@end

@implementation MyView

- (instancetype)init; {
    self = [super init];
    if (self) {
        NSLog(@"%s", __FUNCTION__);
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        NSLog(@"%s | %@", __FUNCTION__, NSStringFromCGRect(frame));
    }
    return self;
}

@end

并且通过调用 [[MyView alloc] init]; 它打印:

-[MyView initWithFrame:] | {{0, 0}, {0, 0}}
-[MyView init]

更新

这里是 Swift 版本:

class MyView: UIView {
    override init() {
        super.init()
        println(__FUNCTION__)
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        println("\(__FUNCTION__) | \(frame)")
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        println(__FUNCTION__)
    }
}

然后您只需在代码中的某处调用 MyView()

为Swift4.0 只需在委托方法中添加以下代码

func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
    return CGFloat.leastNormalMagnitude
}