Go Back   MacRumors Forums > Apple Systems and Services > Programming > iPhone/iPad Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Jan 14, 2013, 03:16 PM   #1
Chirone
macrumors 6502
 
Join Date: Mar 2009
Location: NZ
Auto layout on image view

Hi, I want to put an image view on the left of a table view in landscape and above it in portrait.

So I have to do this in code. now... for landscape I have this constraint added
Code:
[NSLayoutConstraint constraintsWithVisualFormat:@"|-[imageView]-(20)-[tableView(280)]-|"
							 options:NSLayoutFormatAlignAllTop
							 metrics:nil
							   views:views];
As you can see from the string format...
- the left edge and the image view is the default space of 20,
- the image view has a width that I don't care about,
- the image view should resize
- there should be 20 pixels between the image view and table view
- the table view should be 280 wide
- and there should be a default space of 20 between the table view and the right edge.

now... this doesn't work. The image view resizes fine, but it complains about conflicting constraints.
It seems to think that the image view HAS to be a particular size.
Even if I set the hugging and compression resistance of the image view to be less than the table view it still has this issue.

it complains and says it has to break the -(20)- between the image and the table view (which doesn't make sense because it resizes the image view)

I can change the spacing between views and edges to an inequality and it won't complain (but wont show up right)

I can give the image view an explicit size and let the table view not have an explicit size and it won't complain.

does anyone know what I might be doing wrong? Do I need to give more info for this to make sense?
Chirone is offline   0 Reply With Quote
Old Jan 16, 2013, 06:33 AM   #2
KoolStar
macrumors Demi-God
 
KoolStar's Avatar
 
Join Date: Oct 2006
Location: Kentucky
Send a message via AIM to KoolStar Send a message via Skype™ to KoolStar
I would recommend on viewDidLoad to copy all the current constraints into an array. I would also create an array of constraints from your ascii art form. Thus you will have two arrays one for portrait constraints and one for landscape constraints. On rotation you can swap out the constraints. That is one possible solution. Without seeing the project I cant determine what constraints you should manually remove or add.

I can however give you a nice macro to debug autolayout that I have come up with.

Code:
    #define ALMasterLog(view) NSLog((@"%s [Line %d] \r\r %@ \r\r %@ \r %@"), __PRETTY_FUNCTION__, __LINE__, [view performSelector:@selector(recursiveDescription)], [[view constraints] description], [view performSelector:@selector(_autolayoutTrace)]);
That macro can be used by adding it to the class or pre compiled header to have access to it in any class.

You simply need to call ALMasterLog(self.view) or some view in it. This will print out some basic information first such as the function its called in and the line of the call. After that it will print a recursive description of the view hierarchy followed by all constraints currently on that view and will show any ambiguous layouts. A sample of the output is below.

Code:
2013-01-16 07:31:22.205 Constraints_Hybrid[21115:c07] -[ViewController applyConstraintsForInterfaceOrientation:] [Line 76] 

 <UIView: 0x7482c10; frame = (0 0; 768 1004); autoresize = W+H; gestureRecognizers = <NSArray: 0x74833b0>; layer = <CALayer: 0x7482c70>>
   | <UIView: 0x747f990; frame = (394 20; 354 964); autoresize = W+H; gestureRecognizers = <NSArray: 0x7481b20>; layer = <CALayer: 0x747ed30>>
   |    | <UILabel: 0x747fae0; frame = (138 472; 78 21); text = 'View Gold'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; gestureRecognizers = <NSArray: 0x747fec0>; layer = <CALayer: 0x747fba0>>
   | <UIView: 0x7481b80; frame = (20 20; 354 472); autoresize = RM+BM; gestureRecognizers = <NSArray: 0x7482490>; layer = <CALayer: 0x7481be0>>
   |    | <UILabel: 0x7481c10; frame = (128 225; 99 21); text = 'View Orange'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; gestureRecognizers = <NSArray: 0x7481ea0>; layer = <CALayer: 0x7481ca0>>
   | <UIView: 0x74824f0; frame = (20 512; 354 472); autoresize = RM+BM; gestureRecognizers = <NSArray: 0x7482bc0>; layer = <CALayer: 0x7482550>>
   |    | <UILabel: 0x7482580; frame = (138 226; 79 21); text = 'View Grey'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; gestureRecognizers = <NSArray: 0x7482760>; layer = <CALayer: 0x7482610>> 

 (
    "<NSLayoutConstraint:0x7482d40 V:|-(NSSpace(20))-[UIView:0x7481b80]   (Names: '|':UIView:0x7482c10 )>",
    "<NSLayoutConstraint:0x7482da0 H:|-(NSSpace(20))-[UIView:0x7481b80]   (Names: '|':UIView:0x7482c10 )>",
    "<NSLayoutConstraint:0x7482de0 H:[UIView:0x7481b80]-(394)-|   (Names: '|':UIView:0x7482c10 )>",
    "<NSLayoutConstraint:0x7482e20 V:[UIView:0x747f990]-(NSSpace(20))-|   (Names: '|':UIView:0x7482c10 )>",
    "<NSLayoutConstraint:0x7482e60 H:|-(394)-[UIView:0x747f990]   (Names: '|':UIView:0x7482c10 )>",
    "<NSLayoutConstraint:0x7482ea0 V:|-(NSSpace(20))-[UIView:0x747f990]   (Names: '|':UIView:0x7482c10 )>",
    "<NSLayoutConstraint:0x7482ee0 H:[UIView:0x747f990]-(NSSpace(20))-|   (Names: '|':UIView:0x7482c10 )>",
    "<NSLayoutConstraint:0x7482f20 H:|-(NSSpace(20))-[UIView:0x74824f0]   (Names: '|':UIView:0x7482c10 )>",
    "<NSLayoutConstraint:0x7482f60 V:[UIView:0x74824f0]-(NSSpace(20))-|   (Names: '|':UIView:0x7482c10 )>",
    "<NSLayoutConstraint:0x7482fa0 V:|-(512)-[UIView:0x74824f0]   (Names: '|':UIView:0x7482c10 )>",
    "<NSLayoutConstraint:0x7482fe0 UIView:0x74824f0.width == UIView:0x7481b80.width>",
    "<NSLayoutConstraint:0x7483020 UIView:0x74824f0.height == UIView:0x7481b80.height>"
) 
 
*<UIView:0x7482c10>
|   *<UIView:0x747f990>
|   |   *<UILabel:0x747fae0>
|   *<UIView:0x7481b80>
|   |   *<UILabel:0x7481c10>
|   *<UIView:0x74824f0>
|   |
I am also including a sample code file to show you what i was talking about with adding and removing all constraints on rotation.

Code:
#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, weak) IBOutlet UIView *orangeView, *greyView, *goldView;
@property (nonatomic, strong) NSArray *myLConstraints, *myPConstraints;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self setupConstraints];
    [self applyConstraintsForInterfaceOrientation:[[UIApplication sharedApplication] statusBarOrientation]];
}

- (void)setupConstraints
{
    _myPConstraints = [self.view constraints];
    
    if (_myLConstraints) return;
    NSMutableArray *constraints = [NSMutableArray array];
    
    NSDictionary *views = NSDictionaryOfVariableBindings(_orangeView, _greyView, _goldView);
    NSDictionary *metrics = NSDictionaryOfVariableBindings(@20);
    
    NSArray *hConstriants = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_orangeView(==_greyView)]-20-[_greyView(==_orangeView)]-|"
                                                                    options:NSLayoutFormatDirectionLeftToRight
                                                                    metrics:metrics
                                                                      views:views];
    
    NSArray *vConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[_orangeView(300)]-20-[_goldView]-|"
                                                                    options:NSLayoutFormatDirectionLeadingToTrailing
                                                                    metrics:metrics
                                                                      views:views];
    
    NSArray *v1Constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[_greyView]-20-[_goldView]-|"
                                                                    options:NSLayoutFormatDirectionLeadingToTrailing
                                                                    metrics:metrics
                                                                      views:views];
    NSArray *h1Constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_goldView]-|"
                                                                    options:NSLayoutFormatDirectionLeadingToTrailing
                                                                    metrics:metrics
                                                                      views:views];
    
    
    [self mergeArraysInto:&constraints, hConstriants, h1Constraints, vConstraints, v1Constraints, nil];
    _myLConstraints = (NSArray*)constraints;
    return;

}

- (void)applyConstraintsForInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    if (UIInterfaceOrientationIsLandscape(interfaceOrientation))
    {
        [self.view removeConstraints:_myPConstraints];
        [self.view addConstraints:_myLConstraints];
    }
    else
    {
        [self.view removeConstraints:_myLConstraints];
        [self.view addConstraints:_myPConstraints];
    }
    //ALCLog(self.view);
    //ALAMBLog(self.view);
    ALMasterLog(self.view);
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [self applyConstraintsForInterfaceOrientation:toInterfaceOrientation];
}

- (void)mergeArraysInto:(NSMutableArray**)intoArray, ...
{
    NSArray *eachObject;
    va_list argumentList;
    if (intoArray) // The first argument isn't part of the varargs list,
    {
        va_start(argumentList, intoArray); // Start scanning for arguments after firstObject.
        while ((eachObject = va_arg(argumentList, NSArray*))) // As many times as we can get an argument of type "id"
        {
            [*intoArray addObjectsFromArray:eachObject]; // that isn't nil, add it to self's contents.
        }
        va_end(argumentList);
    }
}

@end
__________________
"Innovation distinguishes between a leader and a follower." : S.J.
KoolStar is offline   0 Reply With Quote
Old Jan 16, 2013, 01:42 PM   #3
Chirone
Thread Starter
macrumors 6502
 
Join Date: Mar 2009
Location: NZ
Hey thanks for that!

Pretty detailed there. I'll give it a whirl when I get a chance.
Chirone is offline   0 Reply With Quote
Old Jan 17, 2013, 06:13 AM   #4
KoolStar
macrumors Demi-God
 
KoolStar's Avatar
 
Join Date: Oct 2006
Location: Kentucky
Send a message via AIM to KoolStar Send a message via Skype™ to KoolStar
Your quit welcome, if you need anymore help with auto layout or anything else don't hesitate to ask.
__________________
"Innovation distinguishes between a leader and a follower." : S.J.
KoolStar is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > iPhone/iPad Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Similar Threads
thread Thread Starter Forum Replies Last Post
Auto Layout Problem erdinc27 iPhone/iPad Programming 7 Jul 26, 2013 03:17 PM
Auto Layout Worth It? loon3y iPhone/iPad Programming 8 Jul 19, 2013 06:20 AM
Auto Layout and Hiding Embedded View Controllers isthisonetaken iPhone/iPad Programming 2 Dec 9, 2012 03:47 PM
View based table view layout woes Starfox Mac Programming 0 Nov 8, 2012 10:50 PM
Auto Layout Feature npggirl iOS 6 0 Jun 18, 2012 12:43 PM

Forum Jump

All times are GMT -5. The time now is 03:57 AM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC