monyschuk/LITabControl

Problem when initializing LITabControl

Opened this issue · 6 comments

Hi Mark,

LITabControl's design is great, especially the idea that including the actual item into each segment. But when I was testing LITabControl, I found that in order for it to initialize properly, the super's -initWithFrame: has to be called. However, when being initialized from the storyboard, -initWithCoder is called instead of the -initWithFrame. As a result, the control won't work.

As a temporary solution, I added the -initWithCoder method like below:

- (instancetype)initWithCoder:(NSCoder *)coder {
    if (self = [super initWithCoder:coder]) {
        self = [super initWithFrame:self.frame];
        [self configureSubviews];
    }

    return self;
}

The code above looks really odd, but it seems to solve the problem for now. Any new ideas?

Calling init twice on the same object can cause subtle bugs that are very hard to track down.

This is especially true for CALayer objects.

For this reason, I’ve adopted the following [self doInit] design pattern for ALL of my NSView subclasses.

It is OK for my private doInit to be called multiple times, but its not OK for [NSView init] to be called multiple times.

Example:

@interface VEditableTextField : NSTextField
{
}
@EnD

@implementation VEditableTextField
-(void)doInit
{
if ( [super respondsToSelector:@selector(doInit)] )
[super doInit];
drawsBorder = NO;
isEditing = NO;
editingAlignmentRect = [self bounds];
isSettingUpFieldEditor = NO;
[self setSelectable:YES];
[self setEditable:YES];

[[self cell] setScrollable:NO]; // NSCell
[[self cell] setWraps:NO];

[self setFocusRingType: NSFocusRingTypeNone]; // we will draw our own
}

-(id)initWithFrame:(NSRect)frameRect
{
self = [super initWithFrame:frameRect];
[self doInit];
return self;
}

-(id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
[self doInit];
return self;
}

-(id)init
{
self = [super init];
[self doInit];
return self;
}

...
@EnD

Keith Knauber
Senior Software Engineer


Production Resource Group
8617 Ambassador Row, Suite 120
Dallas, Texas 75247
214-819-3145 Phone
214-477-3928 Mobile
kknauber@prg.commailto:creese@prg.com
www.prg.comhttp://www.prg.com/

On Apr 21, 2015, at 11:12 AM, Renfei Song <notifications@github.commailto:notifications@github.com> wrote:

Hi Mark,

LITabControl's design is great, especially the idea that including the actual item into each segment. But when I was testing LITabControl, I found that in order for it to initialize properly, the -initWithFrame: has to be called. However, when being initialized from the storyboard, -initWithCoder is called instead of the -initWithFrame. As a result, the control won't work.

As a temporary solution, I added the -initWithCoder method like below:

  • (instancetype)initWithCoder:(NSCoder *)coder {
    if (self = [super initWithCoder:coder]) {
    self = [super initWithFrame:self.frame];
    [self configureSubviews];
    }

    return self;
    }

Looks really wired, but it seems to solve the problem for now. Any new ideas?


Reply to this email directly or view it on GitHubhttps://github.com//issues/8.

I have the same problem as renfeisong. super's initWithFrame method had to be called for using this control. I don't know how to avoid it. renfeisong posted a code, it works, but seems too tricky.

Indeed, LITabControl occasionally have funny behaviors with the snippet I posted above, although I do not know the exact reason. In the end I had to roll my own tab control instead of using LITabControl.

So you don't recommend to use this control with this snippet? Also, did you use https://github.com/ajin/MMTabBarView ?

Yes. Before somebody fixes the problem, any dirty/temporary workaround may potentially lead to bugs. MMTabBarView seems to be a good alternative, but I haven't used it.

Okay, thank you!