Autolayout horizontal stack view

Leave a comment

Say you want to layout several components together in a StackView like this

Screen Shot 2017-01-20 at 7.43.16 AM.png

Drag out the stackview

Screen Shot 2017-01-20 at 7.45.01 AM.png

And stretch it out

Screen Shot 2017-01-20 at 7.47.50 AM.png

Then make it the same width as the image above. Control drag the stackview to the image

Screen Shot 2017-01-20 at 7.49.19 AM.png

Screen Shot 2017-01-20 at 7.49.25 AM.png

Next give it a height. In this case 70.

Screen Shot 2017-01-20 at 7.50.37 AM.png

Screen Shot 2017-01-20 at 7.50.46 AM.png

Then center it to the label above. Control drag the view to the artist label.

Screen Shot 2017-01-20 at 7.51.37 AM.png

Screen Shot 2017-01-20 at 7.52.09 AM.png

Then give it some distance between it and the label above.

Screen Shot 2017-01-20 at 7.53.23 AM.png

Screen Shot 2017-01-20 at 7.53.38 AM.png

Cmd + alt + = to readjust the layout…

Screen Shot 2017-01-20 at 7.54.20 AM.png

And now we can add in the components. Drag in a button and a progress bar.

Screen Shot 2017-01-20 at 7.55.21 AM.png

Put the progress bar in the middle by changing the horiztal stack view alignment property.

Screen Shot 2017-01-20 at 7.56.13 AM.png

Screen Shot 2017-01-20 at 7.56.20 AM.png

And then style and set sizes for the button however you wish. In this case 70×70.

Screen Shot 2017-01-20 at 7.57.41 AM.png

Screen Shot 2017-01-20 at 7.57.48 AM.png

You can then tune it up however you wish.

 

 

 

 

Autolayout a simple component

Leave a comment

To autolayout a simple a component like this

Screen Shot 2017-01-20 at 6.24.58 AM.png

Start by setting a width

Screen Shot 2017-01-20 at 6.26.05 AM.png

Then center horizontally

Screen Shot 2017-01-20 at 6.27.36 AM.png

Then pin it to the top

Screen Shot 2017-01-20 at 6.28.31 AM.png

And voila! You constraint compliant component.

Screen Shot 2017-01-20 at 6.29.01 AM.png

How to layout UILabel relative to UIImageView

Leave a comment

So you have a label ‘Title’ you want to add constraints to so that it looks like this

Screen Shot 2017-01-19 at 7.57.32 AM.png

We will first make the label and the UIImageView equal width by command selecting them both

Screen Shot 2017-01-19 at 8.01.31 AM.png

Screen Shot 2017-01-19 at 8.02.06 AM.png

Then add a top space constraint between the label and the image by

Screen Shot 2017-01-19 at 8.05.43 AM.png

Screen Shot 2017-01-19 at 8.05.51 AM.png

And then constrain the X position of the label by aligning the label to the super view

Screen Shot 2017-01-19 at 8.07.30 AM.png

Screen Shot 2017-01-19 at 8.07.39 AM.png

Then re-adjust the layout with good ol cmd + alt + =

Voila!

Screen Shot 2017-01-19 at 8.08.37 AM.png

Note : if you want to horizontally align with the element above you (instead of the whole container) control drag from the button or label you want to align to the element you want to align with.

Screen Shot 2017-01-19 at 8.56.29 AM.png

And if you want to add a play button into the middle of the UIImageView, select both and then

Screen Shot 2017-01-19 at 2.49.17 PM.png

Screen Shot 2017-01-19 at 2.49.43 PM.png

Trouble shooting

If you are having trouble command selecting both elements (for example to set the equal widths) check to see that your label or button didn’t get buried somewhere deep in another view.

For example here I am trying to add another label, and here I want to make it the same width as the title one above. But I can’t select them. It’s because my artist label got buried in another view.

Screen Shot 2017-01-19 at 8.15.30 AM.png

So fix this, drag the label out to the appropriate level.

Screen Shot 2017-01-19 at 8.17.16 AM.png

You should now be able to select shift select both (hold down shift while clicking on each).

Screen Shot 2017-01-19 at 8.18.01 AM.png

 

 

How to make an HTTP GET json call objective c

Leave a comment


typedef void (^MessageCallback)(id _Nullable result, NSError * _Nullable error);

@implementation MessageTrackAPI

+ (void)fetchTrackForSomeIdId:(NSString *)someId callback:(nullable MessageCallback)callback
{
        NSString *queryString = [NSString stringWithFormat:@"https://api.xxx.com/v1/tracks/%@",someId];
        NSURL *url = [NSURL URLWithString:queryString];
        NSURLSession *session = [NSURLSession sharedSession];
        NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler: ^(NSData *data, NSURLResponse *response, NSError *error) {
            NSMutableArray *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];

            // print as json
            NSData *jsonData = [NSJSONSerialization dataWithJSONObject:json options:NSJSONWritingPrettyPrinted error:&error];
            NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

            NSLog(@"%@", jsonString);
            MessageTrack *track = [MessageTrackParser parseJson:json];
            callback(track, nil);
        }];
    
        [task resume];
}

How to convert json NSArray into NSString

Leave a comment

NSArray *myArray;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:myArray options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

Always update UI elements on the main thread

Leave a comment

If you ever get an error message that says “You are corrupting the autolayout engine because you are attempting to update UI elements while not being on the main thread” try putting all your update code in a dispatch main queue. Something like this.

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
    [SPTMessageSearchAPI fetchTracksForQuery:searchBar.text callback:^(id  _Nullable result, NSError * _Nullable error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            self.tracks = (NSArray *)result;
            [self.collectionView reloadData];
        });
    }];
}

This will let you do other UI elements updates later when re-rendering cells and avoid that corrupt error message.

@implementation SPTMessageTrackCollectionViewCell

- (void)layoutWithTrack:(SPTMessageTrack *)track {
    NSAssert([NSThread isMainThread], @"must be called from main thread");

    // todo - See SpotifyItemCollectionViewCell for example of how to lookup smallest album cover
    self.headerLabel.text = track.title;
    self.subheaderLabel.text = track.artist;
    [self.imageView sd_setImageWithURL:[NSURL URLWithString:track.imageUrl]];
}

This application is modifying the autolayout engine from a background thread after the engine was accessed from the main thread. This can lead to engine corruption and weird crashes.

Leave a comment

If you ever get this error while doing autolayout, catch it by setting a symbolic break point.

Screen Shot 2017-01-13 at 9.01.54 AM.png

Can also add an action like this

Screen Shot 2017-01-13 at 9.09.40 AM.png

And then see in output like this

Screen Shot 2017-01-13 at 9.10.43 AM.png

The way to fix it is to dispatch things on the mainthread and not in the background.

dispatch_async(dispatch_get_main_queue(), ^{
    // code here
});

http://stackoverflow.com/questions/28302019/getting-a-this-application-is-modifying-the-autolayout-engine-error

Older Entries

%d bloggers like this: