Skip to content

Instantly share code, notes, and snippets.

@uptown
Last active August 29, 2015 14:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save uptown/165770a7f6e012f83026 to your computer and use it in GitHub Desktop.
Save uptown/165770a7f6e012f83026 to your computer and use it in GitHub Desktop.
iOS Auto-adjusting autolayout snippet with some tricks
//
// NSObject+UTFrameworkProtected.h
// UTFramework
//
// Created by Juyoung Lee on 2014. 1. 2..
// Copyright (c) 2014년 Juyoung.me. All rights reserved.
//
#import <Foundation/Foundation.h>
// NSObject내에 저장된 callback을 실행시키는 핼퍼
static char* kUTFrameworkBlockKey = "kUTFrameworkBlockKey";
@interface NSObject (UTFrameworkProtected)
- (void)_invokeBlock:(id)sender;
@end
//
// NSObject+UTFrameworkProtected.m
// UTFramework
//
// Created by Juyoung Lee on 2014. 1. 2..
// Copyright (c) 2014년 Juyoung.me. All rights reserved.
//
#import "NSObject+UTFrameworkProtected.h"
#import "NSObject+UTFramework.h"
@implementation NSObject (UTFrameworkProtected)
- (void)_invokeBlock:(id)sender {
UTActionBlock block = [self associatedValueForKey:kUTFrameworkBlockKey];
if (block)
block(sender);
}
@end
//
// AutoScaleViewController.h
//
//
// Created by Lee, Juyoung on 2015. 7. 5..
// Copyright (c) 2015년 Juyoung. All rights reserved.
//
#import <UIKit/UIKit.h>
// localized string을 런타임시 컨트롤하기 위한 최상위 뷰컨트롤러
@interface AutoScaleViewController : UIViewController
- (CGSize)originalSize;
- (CGSize)currentSize;
@end
//
// AutoScaleViewController.m
//
//
// Created by Lee, Juyoung on 2015. 7. 5..
// Copyright (c) 2015년 Juyoung. All rights reserved.
//
#import "AutoScaleViewController.h"
#import "UIVIew+SmartLayout.h"
@interface AutoScaleViewController ()
@end
@implementation AutoScaleViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self updateViewConstraintsForView:self.view];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.view doSmartLayout:[self originalSize] toSize:[self currentSize]];
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
- (void)updateViewConstraintsForView:(UIView *)view{
CGSize original = [self originalSize];
CGSize current = [self currentSize];
// NSLog(@"%@ => %@", NSStringFromCGSize(original), NSStringFromCGSize(current));
NSMutableArray *newConstraints = [NSMutableArray array];
for(NSLayoutConstraint *constraint in view.constraints){
// NSLog(@"%@\n %d %d \n%@\n %d %f %f", constraint.firstItem, constraint.firstAttribute, constraint.relation, constraint.secondItem, constraint.secondAttribute, constraint.multiplier, constraint.constant);
if(constraint.multiplier == 1.0f){
// constraint.firstAttribute = constraint.firstAttribute * (current.width /original.width);
}
if( constraint.firstAttribute == NSLayoutAttributeTop
|| constraint.firstAttribute == NSLayoutAttributeBottom
|| constraint.firstAttribute == NSLayoutAttributeHeight
|| constraint.firstAttribute == NSLayoutAttributeCenterY
|| constraint.firstAttribute == NSLayoutAttributeBaseline
|| constraint.firstAttribute == NSLayoutAttributeFirstBaseline
|| constraint.firstAttribute == NSLayoutAttributeTopMargin
|| constraint.firstAttribute == NSLayoutAttributeBottomMargin
|| constraint.firstAttribute == NSLayoutAttributeCenterYWithinMargins
){
if(constraint.firstAttribute == NSLayoutAttributeHeight && [constraint.firstItem isKindOfClass:[UIImageView class]]){
[newConstraints addObject:[NSLayoutConstraint constraintWithItem:constraint.firstItem attribute:constraint.firstAttribute relatedBy:constraint.relation toItem:constraint.secondItem attribute:constraint.secondAttribute multiplier:constraint.multiplier constant:constraint.constant * current.width / original.width]];
}
else{
[newConstraints addObject:[NSLayoutConstraint constraintWithItem:constraint.firstItem attribute:constraint.firstAttribute relatedBy:constraint.relation toItem:constraint.secondItem attribute:constraint.secondAttribute multiplier:constraint.multiplier constant:constraint.constant * current.height / original.height]];
}
}
else if(constraint.firstAttribute == NSLayoutAttributeLeft
|| constraint.firstAttribute == NSLayoutAttributeRight
|| constraint.firstAttribute == NSLayoutAttributeWidth
|| constraint.firstAttribute == NSLayoutAttributeCenterX
|| constraint.firstAttribute == NSLayoutAttributeLeftMargin
|| constraint.firstAttribute == NSLayoutAttributeRightMargin
|| constraint.firstAttribute == NSLayoutAttributeCenterXWithinMargins
){
[newConstraints addObject:[NSLayoutConstraint constraintWithItem:constraint.firstItem attribute:constraint.firstAttribute relatedBy:constraint.relation toItem:constraint.secondItem attribute:constraint.secondAttribute multiplier:constraint.multiplier constant:constraint.constant * current.width / original.width]];
}
else{
[newConstraints addObject:constraint];
}
}
[view removeConstraints:view.constraints];
[view addConstraints:newConstraints];
for(UIView *subview in view.subviews){
[self updateViewConstraintsForView:subview];
}
}
- (CGSize)originalSize{
return CGSizeMake(320, 568);
}
- (CGSize)currentSize{
return self.view.frame.size;
}
@end
//
// NSObject+UTFramework.h
// UTFramework
//
// Created by Juyoung Lee on 2014. 1. 2..
// Copyright (c) 2014년 Juyoung.me. All rights reserved.
//
#import <Foundation/Foundation.h>
// Object에 데이터를 저장하기 위한 helper NSObject를 상속받은 모든 객체는 이 함수를 통해 객체내부에 데이터 저장이 가능하다.
// 보통 callback등을 저장하는데 사용되거나, static 변수등으로 처리하기 까다로울때 사용된다.
typedef void (^UTActionBlock)(id sender);
@interface NSObject (UTFramework)
- (void)retainAssociateValue:(id)value withKey:(const char *)key;
- (void)copyAssociateValue:(id)value withKey:(const char *)key;
- (void)assignAssociateValue:(id)value withKey:(const char *)key;
- (id)associatedValueForKey:(const char *)key;
- (void)removeAllAssociatedObjects;
+ (void)retainAssociateValue:(id)value withKey:(const char *)key;
+ (void)copyAssociateValue:(id)value withKey:(const char *)key;
+ (void)assignAssociateValue:(id)value withKey:(const char *)key;
+ (id)associatedValueForKey:(const char *)key;
+ (void)removeAllAssociatedObjects;
@end
//
// NSObject+UTFramework.m
// UTFramework
//
// Created by Juyoung Lee on 2014. 1. 2..
// Copyright (c) 2014년 Juyoung.me. All rights reserved.
//
#import "NSObject+UTFramework.h"
#import <objc/runtime.h>
@implementation NSObject (UTFramework)
- (void)retainAssociateValue:(id)value withKey:(const char *)key {
objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)copyAssociateValue:(id)value withKey:(const char *)key {
objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (void)assignAssociateValue:(id)value withKey:(const char *)key {
objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_ASSIGN);
}
- (id)associatedValueForKey:(const char *)key {
return objc_getAssociatedObject(self, key);
}
- (void)removeAllAssociatedObjects {
objc_removeAssociatedObjects(self);
}
+ (void)retainAssociateValue:(id)value withKey:(const char *)key {
objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
+ (void)copyAssociateValue:(id)value withKey:(const char *)key {
objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
+ (void)assignAssociateValue:(id)value withKey:(const char *)key {
objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_ASSIGN);
}
+ (id)associatedValueForKey:(const char *)key {
return objc_getAssociatedObject(self, key);
}
+ (void)removeAllAssociatedObjects {
objc_removeAssociatedObjects(self);
}
@end
//
// UIView+SmartLayout.h
// UTFramework
//
// Created by Juyoung Lee on 2014. 1. 2..
// Copyright (c) 2014년 Juyoung.me. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIView (SmartLayout)
- (void)doSmartLayout:(CGSize)originalSize toSize:(CGSize)toSize;
- (void)smartLayout:(CGSize)originalSize toSize:(CGSize)toSize;
@end
//
// UIView+SmartLayout.m
// UTFramework
//
// Created by Juyoung Lee on 2014. 1. 2..
// Copyright (c) 2014년 Juyoung.me. All rights reserved.
//
#import "UIVIew+SmartLayout.h"
#import "NSObject+UTFramework.h"
#import "UILabel+SmartLayout.h"
@implementation UIView (SmartLayout)
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
- (void)smartLayout:(CGSize)originalSize toSize:(CGSize)toSize{
[self doSmartLayout:originalSize toSize:toSize];
}
- (void)doSmartLayout:(CGSize)originalSize toSize:(CGSize)toSize{
static char *smartLayoutChar = "kSmartLayoutKey";
NSNumber *val = [self associatedValueForKey:smartLayoutChar];
if(![val boolValue]){
[self copyAssociateValue:@YES withKey:smartLayoutChar];
[self smartLayout:originalSize toSize:toSize];
for(UIView *view in self.subviews){
[view smartLayout:originalSize toSize:toSize];
}
}
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment