1

I'm trying to create my custom view that will be loaded from nib file.

So I have 3 files: CustomView.h, CustomView.m, CustomView.xib.

As I need this view in my storyboard, I'm trying to load it in initWithCoder: method:

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];

    if (self != nil) {
        UIView *view = [[NSBundle bundleForClass:[self class]] loadNibNamed:KVBTimerViewNibName owner:self options:nil].firstObject;
        [self addSubview:view];
    }

    return self;
}

But in this case view size is much more bigger than I need(I need the same size as my view has).

I tried to add constraints for width and height, but them I'm getting runtime error:

    2015-06-22 16:17:27.492 KVBTimer[8289:993411] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x7f9e0bf19090 V:[KVBTimerView:0x7f9e0bf18a90(250)]>",
    "<NSLayoutConstraint:0x7f9e0bf1bda0 V:|-(0)-[UIView:0x7f9e0bf1fba0]   (Names: '|':KVBTimerView:0x7f9e0bf18a90 )>",
    "<NSLayoutConstraint:0x7f9e0bf1f700 UIView:0x7f9e0bf1fba0.bottom == KVBTimerView:0x7f9e0bf18a90.bottom>",
    "<NSAutoresizingMaskLayoutConstraint:0x7f9e0bf2dfe0 h=--& v=--& UIView:0x7f9e0bf1fba0.midY == + 57>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7f9e0bf1f700 UIView:0x7f9e0bf1fba0.bottom == KVBTimerView:0x7f9e0bf18a90.bottom>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2015-06-22 16:17:27.494 KVBTimer[8289:993411] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x7f9e0bf1b560 H:|-(0)-[UIView:0x7f9e0bf1fba0](LTR)   (Names: '|':KVBTimerView:0x7f9e0bf18a90 )>",
    "<NSLayoutConstraint:0x7f9e0bf1bc80 UIView:0x7f9e0bf1fba0.right == KVBTimerView:0x7f9e0bf18a90.right>",
    "<NSLayoutConstraint:0x7f9e0bf1a090 KVBTimerView:0x7f9e0bf18a90.width == UIView:0x7f9e0bf1eee0.width>",
    "<NSAutoresizingMaskLayoutConstraint:0x7f9e0bf2db80 h=--& v=--& UIView:0x7f9e0bf1fba0.midX == + 223.5>",
    "<NSLayoutConstraint:0x7f9e0bd32960 'UIView-Encapsulated-Layout-Width' H:[UIView:0x7f9e0bf1eee0(375)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7f9e0bf1bc80 UIView:0x7f9e0bf1fba0.right == KVBTimerView:0x7f9e0bf18a90.right>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

New code is:

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];

    if (self != nil) {
        UIView *view = [[NSBundle bundleForClass:[self class]] loadNibNamed:KVBTimerViewNibName owner:self options:nil].firstObject;
        [self addSubview:view];
        NSLayoutConstraint *topConstraint = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0];
    NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0];
    NSLayoutConstraint *leftConstraint = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0.0];
    NSLayoutConstraint *rightConstraint = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0];

    [self addConstraint:topConstraint];
    [self addConstraint:bottomConstraint];
    [self addConstraint:leftConstraint];
    [self addConstraint:rightConstraint];
    }

    return self;
}

Maybe somebody already have code that works? Or can explain where is my problem?

Here is a sample project. Timer view is not in the center.

3 Answers 3

1

to use constraints set translatesAutoresizingMaskIntoConstraints for created view:

subView.translatesAutoresizingMaskIntoConstraints = NO;

add constraints, for example:

NSLayoutConstraint *topConstraint = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0];
NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0];
NSLayoutConstraint *leftConstraint = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0.0];
NSLayoutConstraint *rightConstraint = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0];

[self addConstraint:topConstraint];
[self addConstraint:bottomConstraint];
[self addConstraint:leftConstraint];
[self addConstraint:rightConstraint];

it works for me

Sign up to request clarification or add additional context in comments.

2 Comments

copied your code, but getting the same error with constraints
you should change self.translatesAutoresizingMaskIntoConstraints = NO to view.translatesAutoresizingMaskIntoConstraints = NO. And do it after addSubview
1

Add this method in CustomView.m file

+ (id)createCustomView{
CustomView *customView = [[[NSBundle mainBundle] loadNibNamed:@"CustomView" owner:nil options:nil] lastObject];
// make sure customView is not nil or the wrong class!
if ([customView isKindOfClass:[CustomView class]])
{
    return customView;
}
else
    return nil;}

and in CustomView.h file add + (id)createCustomView;

and call this static method with class name to where you are creating object of it.

Hope it helps

Comments

0

Use this

[[[NSBundle mainBundle] loadNibNamed:@"TableHeaderView"
                                                                owner:self
                                                              options:nil] objectAtIndex:0
                                   ];

1 Comment

The problem is in constraints. Not in owner. I need to handle view from nib size properly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.