Anuj
Anuj

Reputation: 7067

Eliminating extra separator lines for empty rows in UITableView in Swift

While removing the extra separator lines in the tableview using the code, I create an outlet for the tableview in my viewcontroller and then set the

self.tableview.tableFooterView = UIView()

While checking for class UIView, the default initializer has the frame argument,

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
}

Using,

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

also works. When the default initializer is different in the UIView class (which does inherit from a lot of other classes), why does the first method work and not give an error? How are the two lines which remove the separators different(if they are), and which one is more efficient and should be used?

Upvotes: 1

Views: 476

Answers (2)

Tushar
Tushar

Reputation: 39

For Swift 4.0 Just Add the following code in the delegate methods

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

Upvotes: 0

yusuke024
yusuke024

Reputation: 2229

UIView inherits init() from NSObject, that why it's valid and doesn't give any error. Every class in Cocoa(Touch) that works with Objective-C inherits from this class (maybe except NSProxy). And it's clear that UIView has it's frame property default to CGRectZero that why it still does work.

I would say you always go with init(frame:) since it's Designated Initializer for UIView. And it gives a clearer intent to the reader. By using init(), you can't be sure that all the properties will be more properly set than using init(frame:).

Update

After having done some little experiment, I found out that UIView.init() calls UIView.init(frame:) by passing CGRectZero. So, I would say that both are totally equivalent. But, I would still suggest you use init(frame:) since it can express a clearer intent to the reader. But that's up to your style.

Here's the code:

@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

And by calling [[MyView alloc] init]; it prints:

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

Update

Here's the Swift version:

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

Then you just call MyView() somewhere in your code.

Upvotes: 2

Related Questions