Reputation: 7067
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
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
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:)
.
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]
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