├── .gitignore ├── HandyAutoLayout.podspec ├── HandyFrame.podspec ├── LICENSE ├── README.md ├── UIView+HandyAutoLayout.h ├── UIView+HandyAutoLayout.m ├── UIView+LayoutMethods.h └── UIView+LayoutMethods.m /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /HandyAutoLayout.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint HandyAutoLayout.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | 11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 12 | # 13 | # These will help people to find your library, and whilst it 14 | # can feel like a chore to fill in it's definitely to your advantage. The 15 | # summary should be tweet-length, and the description more in depth. 16 | # 17 | 18 | s.name = "HandyAutoLayout" 19 | s.version = "1.0.0" 20 | s.summary = "A handy methods for AutoLayout" 21 | 22 | # This description is used to generate tags and improve search results. 23 | # * Think: What does it do? Why did you write it? What is the focus? 24 | # * Try to keep it short, snappy and to the point. 25 | # * Write the description between the DESC delimiters below. 26 | # * Finally, don't worry about the indent, CocoaPods strips it! 27 | s.description = <<-DESC 28 | A view category for AutoLayout handy methods 29 | DESC 30 | 31 | s.homepage = "https://github.com/casatwy/HandyAutoLayout" 32 | # s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif" 33 | 34 | 35 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 36 | # 37 | # Licensing your code is important. See http://choosealicense.com for more info. 38 | # CocoaPods will detect a license file if there is a named LICENSE* 39 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 40 | # 41 | 42 | s.license = "MIT" 43 | # s.license = { :type => "MIT", :file => "FILE_LICENSE" } 44 | 45 | 46 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 47 | # 48 | # Specify the authors of the library, with email addresses. Email addresses 49 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 50 | # accepts just a name if you'd rather not provide an email address. 51 | # 52 | # Specify a social_media_url where others can refer to, for example a twitter 53 | # profile URL. 54 | # 55 | 56 | s.author = { "CasaTaloyum" => "casatwy@msn.com" } 57 | # Or just: s.author = "CasaTaloyum" 58 | # s.authors = { "CasaTaloyum" => "casatwy@msn.com" } 59 | # s.social_media_url = "http://twitter.com/CasaTaloyum" 60 | 61 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 62 | # 63 | # If this Pod runs only on iOS or OS X, then specify the platform and 64 | # the deployment target. You can optionally include the target after the platform. 65 | # 66 | 67 | # s.platform = :ios 68 | s.platform = :ios, "6.0" 69 | 70 | # When using multiple platforms 71 | # s.ios.deployment_target = "5.0" 72 | # s.osx.deployment_target = "10.7" 73 | # s.watchos.deployment_target = "2.0" 74 | # s.tvos.deployment_target = "9.0" 75 | 76 | 77 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 78 | # 79 | # Specify the location from where the source should be retrieved. 80 | # Supports git, hg, bzr, svn and HTTP. 81 | # 82 | 83 | s.source = { :git => "https://github.com/casatwy/HandyAutoLayout.git", :tag => s.version.to_s } 84 | 85 | 86 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 87 | # 88 | # CocoaPods is smart about how it includes source code. For source files 89 | # giving a folder will include any swift, h, m, mm, c & cpp files. 90 | # For header files it will include any header in the folder. 91 | # Not including the public_header_files will make all headers public. 92 | # 93 | 94 | s.source_files = "UIView+HandyAutoLayout.h", "UIView+HandyAutoLayout.m" 95 | 96 | # s.public_header_files = "Classes/**/*.h" 97 | 98 | 99 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 100 | # 101 | # A list of resources included with the Pod. These are copied into the 102 | # target bundle with a build phase script. Anything else will be cleaned. 103 | # You can preserve files from being cleaned, please don't preserve 104 | # non-essential files like tests, examples and documentation. 105 | # 106 | 107 | # s.resource = "icon.png" 108 | # s.resources = "Resources/*.png" 109 | 110 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave" 111 | 112 | 113 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 114 | # 115 | # Link your library with frameworks, or libraries. Libraries do not include 116 | # the lib prefix of their name. 117 | # 118 | 119 | s.framework = "UIKit" 120 | # s.frameworks = "SomeFramework", "AnotherFramework" 121 | 122 | # s.library = "iconv" 123 | # s.libraries = "iconv", "xml2" 124 | 125 | 126 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 127 | # 128 | # If your library depends on compiler flags you can set them in the xcconfig hash 129 | # where they will only apply to your library. If you depend on other Podspecs 130 | # you can include multiple dependencies to ensure it works. 131 | 132 | s.requires_arc = true 133 | 134 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 135 | # s.dependency "JSONKit", "~> 1.4" 136 | 137 | end 138 | -------------------------------------------------------------------------------- /HandyFrame.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint HandyFrame.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | 11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 12 | # 13 | # These will help people to find your library, and whilst it 14 | # can feel like a chore to fill in it's definitely to your advantage. The 15 | # summary should be tweet-length, and the description more in depth. 16 | # 17 | 18 | s.name = "HandyFrame" 19 | s.version = "1.2.0" 20 | s.summary = "handy methods for frame layout" 21 | 22 | # This description is used to generate tags and improve search results. 23 | # * Think: What does it do? Why did you write it? What is the focus? 24 | # * Try to keep it short, snappy and to the point. 25 | # * Write the description between the DESC delimiters below. 26 | # * Finally, don't worry about the indent, CocoaPods strips it! 27 | s.description = <<-DESC 28 | this is a handy methods for frame layout. 29 | DESC 30 | 31 | s.homepage = "https://github.com/casatwy/HandyAutoLayout" 32 | # s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif" 33 | 34 | 35 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 36 | # 37 | # Licensing your code is important. See http://choosealicense.com for more info. 38 | # CocoaPods will detect a license file if there is a named LICENSE* 39 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 40 | # 41 | 42 | s.license = "MIT" 43 | # s.license = { :type => "MIT", :file => "FILE_LICENSE" } 44 | 45 | 46 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 47 | # 48 | # Specify the authors of the library, with email addresses. Email addresses 49 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 50 | # accepts just a name if you'd rather not provide an email address. 51 | # 52 | # Specify a social_media_url where others can refer to, for example a twitter 53 | # profile URL. 54 | # 55 | 56 | s.author = { "CasaTaloyum" => "casatwy@msn.com" } 57 | # Or just: s.author = "CasaTaloyum" 58 | # s.authors = { "CasaTaloyum" => "casatwy@msn.com" } 59 | # s.social_media_url = "http://twitter.com/CasaTaloyum" 60 | 61 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 62 | # 63 | # If this Pod runs only on iOS or OS X, then specify the platform and 64 | # the deployment target. You can optionally include the target after the platform. 65 | # 66 | 67 | # s.platform = :ios 68 | s.platform = :ios, "5.0" 69 | 70 | # When using multiple platforms 71 | # s.ios.deployment_target = "5.0" 72 | # s.osx.deployment_target = "10.7" 73 | # s.watchos.deployment_target = "2.0" 74 | # s.tvos.deployment_target = "9.0" 75 | 76 | 77 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 78 | # 79 | # Specify the location from where the source should be retrieved. 80 | # Supports git, hg, bzr, svn and HTTP. 81 | # 82 | 83 | s.source = { :git => "https://github.com/casatwy/HandyAutoLayout.git", :tag => s.version.to_s } 84 | 85 | 86 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 87 | # 88 | # CocoaPods is smart about how it includes source code. For source files 89 | # giving a folder will include any swift, h, m, mm, c & cpp files. 90 | # For header files it will include any header in the folder. 91 | # Not including the public_header_files will make all headers public. 92 | # 93 | 94 | s.source_files = "UIView+LayoutMethods.h", "UIView+LayoutMethods.m" 95 | 96 | # s.public_header_files = "Classes/**/*.h" 97 | 98 | 99 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 100 | # 101 | # A list of resources included with the Pod. These are copied into the 102 | # target bundle with a build phase script. Anything else will be cleaned. 103 | # You can preserve files from being cleaned, please don't preserve 104 | # non-essential files like tests, examples and documentation. 105 | # 106 | 107 | # s.resource = "icon.png" 108 | # s.resources = "Resources/*.png" 109 | 110 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave" 111 | 112 | 113 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 114 | # 115 | # Link your library with frameworks, or libraries. Libraries do not include 116 | # the lib prefix of their name. 117 | # 118 | 119 | s.framework = "UIKit" 120 | # s.frameworks = "SomeFramework", "AnotherFramework" 121 | 122 | # s.library = "iconv" 123 | # s.libraries = "iconv", "xml2" 124 | 125 | 126 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 127 | # 128 | # If your library depends on compiler flags you can set them in the xcconfig hash 129 | # where they will only apply to your library. If you depend on other Podspecs 130 | # you can include multiple dependencies to ensure it works. 131 | 132 | s.requires_arc = true 133 | 134 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 135 | # s.dependency "JSONKit", "~> 1.4" 136 | 137 | end 138 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/casatwy/HandyAutoLayout/71afbe23e1451d3f548bf60f35d53153472b63e6/LICENSE -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HandyAutoLayout 2 | 3 | [![CocoaPods compatible](https://img.shields.io/badge/CocoaPods-0.1.1-green.svg?style=flat)](https://cocoapods.org) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](http:// opensource.org/licenses/MIT) 4 | 5 | `HandyAutoLayout` are handy categories for generate NSLayoutConstraint programatically. 6 | 7 | # New features 8 | 9 | ## Add new methods for 1.1.0 10 | ```objective-c 11 | - (void)fromTheTop:(CGFloat)distance ofView:(UIView *)view; 12 | - (void)fromTheBottom:(CGFloat)distance ofView:(UIView *)view; 13 | - (void)fromTheLeft:(CGFloat)distance ofView:(UIView *)view; 14 | - (void)fromTheRight:(CGFloat)distance ofView:(UIView *)view; 15 | ``` 16 | # Install 17 | 18 | if you are using AutoLayout: 19 | 20 | ``` 21 | pod 'HandyAutoLayout' 22 | ``` 23 | 24 | if you are using Frame: 25 | 26 | ``` 27 | pod 'HandyFrame' 28 | ``` 29 | 30 | 31 | # Examples 32 | 33 | for auto layout: 34 | 35 | ```objective-c 36 | [self.view addConstraint:[self.tableView constraintCenterXEqualToView:self.view]]; 37 | [self.view addConstraint:[self.tableView constraintWidthEqualToView:self.view]]; 38 | 39 | [self.view addConstraints:[self.nextStepButton constraintsSize:CGSizeMake(300.0f, 40.0f)]]; 40 | [self.view addConstraint:[self.nextStepButton constraintCenterXEqualToView:self.view]]; 41 | ``` 42 | for frame: 43 | 44 | ```objective-c 45 | [self.subtitleLabel leftEqualToView:self.titleLabel]; 46 | [self.subtitleLabel top:14 FromView:self.timeLabel]; 47 | 48 | [self.createPost centerXEqualToView:self.view]; 49 | [self.createPost bottomInContainer:19.0f shouldResize:NO]; 50 | ``` 51 | -------------------------------------------------------------------------------- /UIView+HandyAutoLayout.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+HandyAutoLayout.h 3 | // ZhanYe 4 | // 5 | // Created by casa on 14-8-25. 6 | // Copyright (c) 2014年 me.andpay. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol HandyAutoLayout 12 | 13 | - (void)addConstraints; 14 | 15 | @end 16 | 17 | @interface UIView (HandyAutoLayout) 18 | 19 | // height 20 | - (NSLayoutConstraint *)constraintHeight:(CGFloat)height; 21 | - (NSLayoutConstraint *)constraintHeightEqualToView:(UIView *)view; 22 | 23 | // width 24 | - (NSLayoutConstraint *)constraintWidth:(CGFloat)width; 25 | - (NSLayoutConstraint *)constraintWidthEqualToView:(UIView *)view; 26 | 27 | // center 28 | - (NSLayoutConstraint *)constraintCenterXEqualToView:(UIView *)view; 29 | - (NSLayoutConstraint *)constraintCenterYEqualToView:(UIView *)view; 30 | 31 | // top, bottom, left, right 32 | - (NSArray *)constraintsTop:(CGFloat)top FromView:(UIView *)view; 33 | - (NSArray *)constraintsBottom:(CGFloat)bottom FromView:(UIView *)view; 34 | - (NSArray *)constraintsLeft:(CGFloat)left FromView:(UIView *)view; 35 | - (NSArray *)constraintsRight:(CGFloat)right FromView:(UIView *)view; 36 | 37 | - (NSArray *)constraintsTopInContainer:(CGFloat)top; 38 | - (NSArray *)constraintsBottomInContainer:(CGFloat)bottom; 39 | - (NSArray *)constraintsLeftInContainer:(CGFloat)left; 40 | - (NSArray *)constraintsRightInContainer:(CGFloat)right; 41 | 42 | - (NSLayoutConstraint *)constraintTopEqualToView:(UIView *)view; 43 | - (NSLayoutConstraint *)constraintBottomEqualToView:(UIView *)view; 44 | - (NSLayoutConstraint *)constraintLeftEqualToView:(UIView *)view; 45 | - (NSLayoutConstraint *)constraintRightEqualToView:(UIView *)view; 46 | 47 | // size 48 | - (NSArray *)constraintsSize:(CGSize)size; 49 | - (NSArray *)constraintsSizeEqualToView:(UIView *)view; 50 | 51 | // imbue 52 | - (NSArray *)constraintsFillWidth; 53 | - (NSArray *)constraintsFillHeight; 54 | - (NSArray *)constraintsFill; 55 | 56 | // assign 57 | - (NSArray *)constraintsAssignLeft; 58 | - (NSArray *)constraintsAssignRight; 59 | - (NSArray *)constraintsAssignTop; 60 | - (NSArray *)constraintsAssignBottom; 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /UIView+HandyAutoLayout.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+HandyAutoLayout.m 3 | // ZhanYe 4 | // 5 | // Created by casa on 14-8-25. 6 | // Copyright (c) 2014年 me.andpay. All rights reserved. 7 | // 8 | 9 | #import "UIView+HandyAutoLayout.h" 10 | 11 | @implementation UIView (HandyAutoLayout) 12 | 13 | - (NSLayoutConstraint *)constraintHeight:(CGFloat)height 14 | { 15 | self.translatesAutoresizingMaskIntoConstraints = NO; 16 | return [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1.0f constant:height]; 17 | } 18 | 19 | - (NSLayoutConstraint *)constraintWidth:(CGFloat)width 20 | { 21 | self.translatesAutoresizingMaskIntoConstraints = NO; 22 | return [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1.0f constant:width]; 23 | } 24 | 25 | - (NSLayoutConstraint *)constraintCenterXEqualToView:(UIView *)view 26 | { 27 | self.translatesAutoresizingMaskIntoConstraints = NO; 28 | return [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f]; 29 | } 30 | 31 | - (NSLayoutConstraint *)constraintCenterYEqualToView:(UIView *)view 32 | { 33 | self.translatesAutoresizingMaskIntoConstraints = NO; 34 | return [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeCenterY multiplier:1.0f constant:0.0f]; 35 | } 36 | 37 | - (NSLayoutConstraint *)constraintHeightEqualToView:(UIView *)view 38 | { 39 | self.translatesAutoresizingMaskIntoConstraints = NO; 40 | return [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeHeight multiplier:1.0f constant:0.0f]; 41 | } 42 | 43 | - (NSLayoutConstraint *)constraintWidthEqualToView:(UIView *)view 44 | { 45 | self.translatesAutoresizingMaskIntoConstraints = NO; 46 | return [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeWidth multiplier:1.0f constant:0.0f]; 47 | } 48 | 49 | - (NSArray *)constraintsTop:(CGFloat)top FromView:(UIView *)view 50 | { 51 | self.translatesAutoresizingMaskIntoConstraints = NO; 52 | UIView *selfView = self; 53 | return [NSLayoutConstraint constraintsWithVisualFormat:@"V:[view]-(top)-[selfView]" options:0 metrics:@{@"top":@(top)} views:NSDictionaryOfVariableBindings(view, selfView)]; 54 | } 55 | 56 | - (NSArray *)constraintsBottom:(CGFloat)bottom FromView:(UIView *)view 57 | { 58 | self.translatesAutoresizingMaskIntoConstraints = NO; 59 | UIView *selfView = self; 60 | return [NSLayoutConstraint constraintsWithVisualFormat:@"V:[selfView]-(bottom)-[view]" options:0 metrics:@{@"bottom":@(bottom)} views:NSDictionaryOfVariableBindings(selfView, view)]; 61 | } 62 | 63 | - (NSArray *)constraintsLeft:(CGFloat)left FromView:(UIView *)view 64 | { 65 | self.translatesAutoresizingMaskIntoConstraints = NO; 66 | UIView *selfView = self; 67 | return [NSLayoutConstraint constraintsWithVisualFormat:@"H:[selfView]-(left)-[view]" options:0 metrics:@{@"left":@(left)} views:NSDictionaryOfVariableBindings(selfView, view)]; 68 | } 69 | 70 | - (NSArray *)constraintsRight:(CGFloat)right FromView:(UIView *)view 71 | { 72 | self.translatesAutoresizingMaskIntoConstraints = NO; 73 | UIView *selfView = self; 74 | return [NSLayoutConstraint constraintsWithVisualFormat:@"H:[view]-(right)-[selfView]" options:0 metrics:@{@"right":@(right)} views:NSDictionaryOfVariableBindings(view, selfView)]; 75 | } 76 | 77 | - (NSArray *)constraintsSizeEqualToView:(UIView *)view 78 | { 79 | self.translatesAutoresizingMaskIntoConstraints = NO; 80 | return @[ 81 | [self constraintHeightEqualToView:view], 82 | [self constraintWidthEqualToView:view] 83 | ]; 84 | } 85 | 86 | - (NSArray *)constraintsSize:(CGSize)size 87 | { 88 | self.translatesAutoresizingMaskIntoConstraints = NO; 89 | return @[ 90 | [self constraintHeight:size.height], 91 | [self constraintWidth:size.width] 92 | ]; 93 | } 94 | 95 | - (NSArray *)constraintsFillWidth 96 | { 97 | self.translatesAutoresizingMaskIntoConstraints = NO; 98 | UIView *selfView = self; 99 | return [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[selfView]-0-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(selfView)]; 100 | } 101 | 102 | - (NSArray *)constraintsFillHeight 103 | { 104 | self.translatesAutoresizingMaskIntoConstraints = NO; 105 | UIView *selfView = self; 106 | return [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[selfView]-0-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(selfView)]; 107 | } 108 | 109 | - (NSArray *)constraintsFill 110 | { 111 | self.translatesAutoresizingMaskIntoConstraints = NO; 112 | NSMutableArray *resultConstraints = [[NSMutableArray alloc] initWithArray:[self constraintsFillWidth]]; 113 | [resultConstraints addObjectsFromArray:[self constraintsFillHeight]]; 114 | return [NSArray arrayWithArray:resultConstraints]; 115 | } 116 | 117 | - (NSArray *)constraintsAssignLeft 118 | { 119 | self.translatesAutoresizingMaskIntoConstraints = NO; 120 | return [self constraintsLeftInContainer:0]; 121 | } 122 | 123 | - (NSArray *)constraintsAssignRight 124 | { 125 | self.translatesAutoresizingMaskIntoConstraints = NO; 126 | return [self constraintsRightInContainer:0]; 127 | } 128 | 129 | - (NSArray *)constraintsAssignTop 130 | { 131 | self.translatesAutoresizingMaskIntoConstraints = NO; 132 | return [self constraintsTopInContainer:0]; 133 | } 134 | 135 | - (NSArray *)constraintsAssignBottom 136 | { 137 | self.translatesAutoresizingMaskIntoConstraints = NO; 138 | return [self constraintsBottomInContainer:0]; 139 | } 140 | 141 | - (NSArray *)constraintsTopInContainer:(CGFloat)top 142 | { 143 | self.translatesAutoresizingMaskIntoConstraints = NO; 144 | UIView *selfView = self; 145 | return [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(top)-[selfView]" options:0 metrics:@{@"top":@(top)} views:NSDictionaryOfVariableBindings(selfView)]; 146 | } 147 | 148 | - (NSArray *)constraintsBottomInContainer:(CGFloat)bottom 149 | { 150 | self.translatesAutoresizingMaskIntoConstraints = NO; 151 | UIView *selfView = self; 152 | return [NSLayoutConstraint constraintsWithVisualFormat:@"V:[selfView]-(bottom)-|" options:0 metrics:@{@"bottom":@(bottom)} views:NSDictionaryOfVariableBindings(selfView)]; 153 | } 154 | 155 | - (NSArray *)constraintsLeftInContainer:(CGFloat)left 156 | { 157 | self.translatesAutoresizingMaskIntoConstraints = NO; 158 | UIView *selfView = self; 159 | return [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(left)-[selfView]" options:0 metrics:@{@"left":@(left)} views:NSDictionaryOfVariableBindings(selfView)]; 160 | } 161 | 162 | - (NSArray *)constraintsRightInContainer:(CGFloat)right 163 | { 164 | self.translatesAutoresizingMaskIntoConstraints = NO; 165 | UIView *selfView = self; 166 | return [NSLayoutConstraint constraintsWithVisualFormat:@"H:[selfView]-(right)-|" options:0 metrics:@{@"right":@(right)} views:NSDictionaryOfVariableBindings(selfView)]; 167 | } 168 | 169 | - (NSLayoutConstraint *)constraintTopEqualToView:(UIView *)view 170 | { 171 | self.translatesAutoresizingMaskIntoConstraints = NO; 172 | return [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0]; 173 | } 174 | 175 | - (NSLayoutConstraint *)constraintBottomEqualToView:(UIView *)view 176 | { 177 | self.translatesAutoresizingMaskIntoConstraints = NO; 178 | return [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeBottom multiplier:1.0f constant:0.0f]; 179 | } 180 | - (NSLayoutConstraint *)constraintLeftEqualToView:(UIView *)view 181 | { 182 | self.translatesAutoresizingMaskIntoConstraints = NO; 183 | return [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeLeft multiplier:1.0f constant:0.0f]; 184 | } 185 | - (NSLayoutConstraint *)constraintRightEqualToView:(UIView *)view 186 | { 187 | self.translatesAutoresizingMaskIntoConstraints = NO; 188 | return [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeRight multiplier:1.0f constant:0.0f]; 189 | } 190 | @end 191 | -------------------------------------------------------------------------------- /UIView+LayoutMethods.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+LayoutMethods.h 3 | // TmallClient4iOS-Prime 4 | // 5 | // Created by casa on 14/12/8. 6 | // Copyright (c) 2014年 casa. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame) 12 | #define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending) 13 | #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) 14 | #define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending) 15 | #define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending) 16 | 17 | #define SCREEN_WIDTH ([[UIScreen mainScreen]bounds].size.width) 18 | #define SCREEN_HEIGHT ([[UIScreen mainScreen]bounds].size.height) 19 | 20 | #define kHPercentage(a) (SCREEN_HEIGHT*((a)/667.00)) 21 | #define kWPercentage(a) (SCREEN_WIDTH *((a)/375.00)) 22 | 23 | #define SCREEN_WITHOUT_STATUS_HEIGHT (SCREEN_HEIGHT - [[UIApplication sharedApplication] statusBarFrame].size.height) 24 | 25 | typedef CGFloat UIScreenType; 26 | 27 | static UIScreenType UIScreenType_iPhone5 = 320.0f; 28 | static UIScreenType UIScreenType_iPhone6 = 375.0f; 29 | static UIScreenType UIScreenType_iPhone6P = 414.0f; 30 | 31 | @interface UIView (LayoutMethods) 32 | 33 | // coordinator getters 34 | - (CGFloat)ct_height; 35 | - (CGFloat)ct_width; 36 | - (CGFloat)ct_x; 37 | - (CGFloat)ct_y; 38 | - (CGSize)ct_size; 39 | - (CGPoint)ct_origin; 40 | - (CGFloat)ct_centerX; 41 | - (CGFloat)ct_centerY; 42 | 43 | - (CGFloat)ct_left; 44 | - (CGFloat)ct_top; 45 | - (CGFloat)ct_bottom; 46 | - (CGFloat)ct_right; 47 | 48 | - (void)setCt_x:(CGFloat)x; 49 | - (void)setCt_left:(CGFloat)left; 50 | - (void)setCt_y:(CGFloat)y; 51 | - (void)setCt_top:(CGFloat)top; 52 | 53 | // height 54 | - (void)setCt_height:(CGFloat)height; 55 | - (void)heightEqualToView:(UIView *)view; 56 | 57 | // width 58 | - (void)setCt_width:(CGFloat)width; 59 | - (void)widthEqualToView:(UIView *)view; 60 | 61 | // size 62 | - (void)setCt_size:(CGSize)size; 63 | - (void)setSize:(CGSize)size screenType:(UIScreenType)screenType; 64 | - (void)sizeEqualToView:(UIView *)view; 65 | 66 | // center 67 | - (void)setCt_centerX:(CGFloat)centerX; 68 | - (void)setCt_centerY:(CGFloat)centerY; 69 | - (void)centerXEqualToView:(UIView *)view; 70 | - (void)centerYEqualToView:(UIView *)view; 71 | - (void)centerEqualToView:(UIView *)view; 72 | 73 | // top, bottom, left, right -- Version 1.1.0 74 | - (void)fromTheTop:(CGFloat)distance ofView:(UIView *)view; 75 | - (void)fromTheBottom:(CGFloat)distance ofView:(UIView *)view; 76 | - (void)fromTheLeft:(CGFloat)distance ofView:(UIView *)view; 77 | - (void)fromTheRight:(CGFloat)distance ofView:(UIView *)view; 78 | 79 | - (void)fromTheRelativeTop:(CGFloat)distance ofView:(UIView *)view screenType:(UIScreenType)screenType; 80 | - (void)fromTheRelativeBottom:(CGFloat)distance ofView:(UIView *)view screenType:(UIScreenType)screenType; 81 | - (void)fromTheRelativeLeft:(CGFloat)distance ofView:(UIView *)view screenType:(UIScreenType)screenType; 82 | - (void)fromTheRelativeRight:(CGFloat)distance ofView:(UIView *)view screenType:(UIScreenType)screenType; 83 | 84 | - (void)relativeTopInContainer:(CGFloat)top shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType; 85 | - (void)relativeBottomInContainer:(CGFloat)bottom shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType; 86 | - (void)relativeLeftInContainer:(CGFloat)left shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType; 87 | - (void)relativeRightInContainer:(CGFloat)right shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType; 88 | 89 | // top, bottom, left, right -- Old Version 90 | - (void)top:(CGFloat)top FromView:(UIView *)view; 91 | - (void)bottom:(CGFloat)bottom FromView:(UIView *)view; 92 | - (void)left:(CGFloat)left FromView:(UIView *)view; 93 | - (void)right:(CGFloat)right FromView:(UIView *)view; 94 | 95 | - (void)topRatio:(CGFloat)top FromView:(UIView *)view screenType:(UIScreenType)screenType; 96 | - (void)bottomRatio:(CGFloat)bottom FromView:(UIView *)view screenType:(UIScreenType)screenType; 97 | - (void)leftRatio:(CGFloat)left FromView:(UIView *)view screenType:(UIScreenType)screenType; 98 | - (void)rightRatio:(CGFloat)right FromView:(UIView *)view screenType:(UIScreenType)screenType; 99 | 100 | - (void)topInContainer:(CGFloat)top shouldResize:(BOOL)shouldResize; 101 | - (void)bottomInContainer:(CGFloat)bottom shouldResize:(BOOL)shouldResize; 102 | - (void)leftInContainer:(CGFloat)left shouldResize:(BOOL)shouldResize; 103 | - (void)rightInContainer:(CGFloat)right shouldResize:(BOOL)shouldResize; 104 | 105 | - (void)topRatioInContainer:(CGFloat)top shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType; 106 | - (void)bottomRatioInContainer:(CGFloat)bottom shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType; 107 | - (void)leftRatioInContainer:(CGFloat)left shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType; 108 | - (void)rightRatioInContainer:(CGFloat)right shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType; 109 | 110 | - (void)topEqualToView:(UIView *)view; 111 | - (void)bottomEqualToView:(UIView *)view; 112 | - (void)leftEqualToView:(UIView *)view; 113 | - (void)rightEqualToView:(UIView *)view; 114 | 115 | // imbueset 116 | - (void)fillWidth; 117 | - (void)fillHeight; 118 | - (void)fill; 119 | 120 | - (UIView *)topSuperView; 121 | 122 | // iPhoneX adapt 123 | - (CGFloat)safeAreaBottomGap; 124 | - (CGFloat)safeAreaTopGap; 125 | - (CGFloat)safeAreaLeftGap; 126 | - (CGFloat)safeAreaRightGap; 127 | 128 | @end 129 | -------------------------------------------------------------------------------- /UIView+LayoutMethods.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+LayoutMethods.m 3 | // TmallClient4iOS-Prime 4 | // 5 | // Created by casa on 14/12/8. 6 | // Copyright (c) 2014年 casa. All rights reserved. 7 | // 8 | 9 | #import "UIView+LayoutMethods.h" 10 | #import 11 | 12 | static void *kUIViewLayoutMethodPropertyBottomGap = &kUIViewLayoutMethodPropertyBottomGap; 13 | static void *kUIViewLayoutMethodPropertyTopGap = &kUIViewLayoutMethodPropertyTopGap; 14 | static void *kUIViewLayoutMethodPropertyLeftGap = &kUIViewLayoutMethodPropertyLeftGap; 15 | static void *kUIViewLayoutMethodPropertyRightGap = &kUIViewLayoutMethodPropertyRightGap; 16 | 17 | @implementation UIView (LayoutMethods) 18 | 19 | // coordinator getters 20 | - (CGFloat)ct_height 21 | { 22 | return self.frame.size.height; 23 | } 24 | 25 | - (CGFloat)ct_width 26 | { 27 | return self.frame.size.width; 28 | } 29 | 30 | - (CGFloat)ct_x 31 | { 32 | return self.frame.origin.x; 33 | } 34 | 35 | - (CGFloat)ct_y 36 | { 37 | return self.frame.origin.y; 38 | } 39 | 40 | - (CGSize)ct_size 41 | { 42 | return self.frame.size; 43 | } 44 | 45 | - (CGPoint)ct_origin 46 | { 47 | return self.frame.origin; 48 | } 49 | 50 | - (CGFloat)ct_centerX 51 | { 52 | return self.center.x; 53 | } 54 | 55 | - (CGFloat)ct_centerY 56 | { 57 | return self.center.y; 58 | } 59 | 60 | - (CGFloat)ct_left 61 | { 62 | return self.frame.origin.x; 63 | } 64 | 65 | - (CGFloat)ct_top 66 | { 67 | return self.frame.origin.y; 68 | } 69 | 70 | - (CGFloat)ct_bottom 71 | { 72 | return self.frame.size.height + self.frame.origin.y; 73 | } 74 | 75 | - (CGFloat)ct_right 76 | { 77 | return self.frame.size.width + self.frame.origin.x; 78 | } 79 | 80 | - (void)setCt_x:(CGFloat)x 81 | { 82 | self.frame = CGRectMake(x, self.frame.origin.y, self.frame.size.width, self.frame.size.height); 83 | } 84 | 85 | - (void)setCt_y:(CGFloat)y 86 | { 87 | self.frame = CGRectMake(self.frame.origin.x, y, self.frame.size.width, self.frame.size.height); 88 | } 89 | 90 | - (void)setCt_left:(CGFloat)left 91 | { 92 | self.ct_x = left; 93 | } 94 | 95 | - (void)setCt_top:(CGFloat)top 96 | { 97 | self.ct_y = top; 98 | } 99 | 100 | - (void)setCt_height:(CGFloat)height 101 | { 102 | CGRect newFrame = CGRectMake(self.ct_x, self.ct_y, self.ct_width, height); 103 | self.frame = newFrame; 104 | } 105 | 106 | - (void)heightEqualToView:(UIView *)view 107 | { 108 | self.ct_height = view.ct_height; 109 | } 110 | 111 | // width 112 | - (void)setCt_width:(CGFloat)width 113 | { 114 | CGRect newFrame = CGRectMake(self.ct_x, self.ct_y, width, self.ct_height); 115 | self.frame = newFrame; 116 | } 117 | 118 | - (void)widthEqualToView:(UIView *)view 119 | { 120 | self.ct_width = view.ct_width; 121 | } 122 | 123 | // center 124 | - (void)setCt_centerX:(CGFloat)centerX 125 | { 126 | CGPoint center = CGPointMake(self.ct_centerX, self.ct_centerY); 127 | center.x = centerX; 128 | self.center = center; 129 | } 130 | 131 | - (void)setCt_centerY:(CGFloat)centerY 132 | { 133 | CGPoint center = CGPointMake(self.ct_centerX, self.ct_centerY); 134 | center.y = centerY; 135 | self.center = center; 136 | } 137 | 138 | - (void)centerXEqualToView:(UIView *)view 139 | { 140 | UIView *superView = view.superview ? view.superview : view; 141 | CGPoint viewCenterPoint = [superView convertPoint:view.center toView:self.topSuperView]; 142 | CGPoint centerPoint = [self.topSuperView convertPoint:viewCenterPoint toView:self.superview]; 143 | self.ct_centerX = centerPoint.x; 144 | } 145 | 146 | - (void)centerYEqualToView:(UIView *)view 147 | { 148 | UIView *superView = view.superview ? view.superview : view; 149 | CGPoint viewCenterPoint = [superView convertPoint:view.center toView:self.topSuperView]; 150 | CGPoint centerPoint = [self.topSuperView convertPoint:viewCenterPoint toView:self.superview]; 151 | self.ct_centerY = centerPoint.y; 152 | } 153 | 154 | - (void)centerEqualToView:(UIView *)view 155 | { 156 | UIView *superView = view.superview ? view.superview : view; 157 | CGPoint viewCenterPoint = [superView convertPoint:view.center toView:self.topSuperView]; 158 | CGPoint centerPoint = [self.topSuperView convertPoint:viewCenterPoint toView:self.superview]; 159 | self.ct_centerX = centerPoint.x; 160 | self.ct_centerY = centerPoint.y; 161 | } 162 | 163 | // top, bottom, left, right -- Version 1.1.0 164 | - (void)fromTheTop:(CGFloat)distance ofView:(UIView *)view 165 | { 166 | [self bottom:distance FromView:view]; 167 | } 168 | 169 | - (void)fromTheBottom:(CGFloat)distance ofView:(UIView *)view 170 | { 171 | [self top:distance FromView:view]; 172 | } 173 | 174 | - (void)fromTheLeft:(CGFloat)distance ofView:(UIView *)view 175 | { 176 | [self left:distance FromView:view]; 177 | } 178 | 179 | - (void)fromTheRight:(CGFloat)distance ofView:(UIView *)view 180 | { 181 | [self right:distance FromView:view]; 182 | } 183 | 184 | 185 | - (void)fromTheRelativeTop:(CGFloat)distance ofView:(UIView *)view screenType:(UIScreenType)screenType 186 | { 187 | [self bottomRatio:distance FromView:view screenType:screenType]; 188 | } 189 | 190 | - (void)fromTheRelativeBottom:(CGFloat)distance ofView:(UIView *)view screenType:(UIScreenType)screenType 191 | { 192 | [self topRatio:distance FromView:view screenType:screenType]; 193 | } 194 | 195 | - (void)fromTheRelativeLeft:(CGFloat)distance ofView:(UIView *)view screenType:(UIScreenType)screenType 196 | { 197 | [self leftRatio:distance FromView:view screenType:screenType]; 198 | } 199 | 200 | - (void)fromTheRelativeRight:(CGFloat)distance ofView:(UIView *)view screenType:(UIScreenType)screenType 201 | { 202 | [self rightRatio:distance FromView:view screenType:screenType]; 203 | } 204 | 205 | 206 | - (void)relativeTopInContainer:(CGFloat)top shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType 207 | { 208 | [self topRatioInContainer:top shouldResize:shouldResize screenType:screenType]; 209 | } 210 | 211 | - (void)relativeBottomInContainer:(CGFloat)bottom shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType 212 | { 213 | [self bottomRatioInContainer:bottom shouldResize:shouldResize screenType:screenType]; 214 | } 215 | 216 | - (void)relativeLeftInContainer:(CGFloat)left shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType 217 | { 218 | [self leftRatioInContainer:left shouldResize:shouldResize screenType:screenType]; 219 | } 220 | 221 | - (void)relativeRightInContainer:(CGFloat)right shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType 222 | { 223 | [self rightRatioInContainer:right shouldResize:shouldResize screenType:screenType]; 224 | } 225 | 226 | 227 | // top, bottom, left, right -- Old Version 228 | - (void)top:(CGFloat)top FromView:(UIView *)view 229 | { 230 | UIView *superView = view.superview ? view.superview : view; 231 | CGPoint viewOrigin = [superView convertPoint:view.ct_origin toView:self.topSuperView]; 232 | CGPoint newOrigin = [self.topSuperView convertPoint:viewOrigin toView:self.superview]; 233 | 234 | self.ct_y = floorf(newOrigin.y + top + view.ct_height); 235 | } 236 | 237 | - (void)bottom:(CGFloat)bottom FromView:(UIView *)view 238 | { 239 | UIView *superView = view.superview ? view.superview : view; 240 | CGPoint viewOrigin = [superView convertPoint:view.ct_origin toView:self.topSuperView]; 241 | CGPoint newOrigin = [self.topSuperView convertPoint:viewOrigin toView:self.superview]; 242 | 243 | self.ct_y = newOrigin.y - bottom - self.ct_height; 244 | } 245 | 246 | - (void)left:(CGFloat)left FromView:(UIView *)view 247 | { 248 | UIView *superView = view.superview ? view.superview : view; 249 | CGPoint viewOrigin = [superView convertPoint:view.ct_origin toView:self.topSuperView]; 250 | CGPoint newOrigin = [self.topSuperView convertPoint:viewOrigin toView:self.superview]; 251 | 252 | self.ct_x = newOrigin.x - left - self.ct_width; 253 | } 254 | 255 | - (void)right:(CGFloat)right FromView:(UIView *)view 256 | { 257 | UIView *superView = view.superview ? view.superview : view; 258 | CGPoint viewOrigin = [superView convertPoint:view.ct_origin toView:self.topSuperView]; 259 | CGPoint newOrigin = [self.topSuperView convertPoint:viewOrigin toView:self.superview]; 260 | 261 | self.ct_x = newOrigin.x + right + view.ct_width; 262 | } 263 | 264 | - (void)topRatio:(CGFloat)top FromView:(UIView *)view screenType:(UIScreenType)screenType 265 | { 266 | CGFloat topRatio = top / screenType; 267 | CGFloat topValue = topRatio * self.superview.ct_width; 268 | [self top:topValue FromView:view]; 269 | } 270 | 271 | - (void)bottomRatio:(CGFloat)bottom FromView:(UIView *)view screenType:(UIScreenType)screenType 272 | { 273 | CGFloat bottomRatio = bottom / screenType; 274 | CGFloat bottomValue = bottomRatio * self.superview.ct_width; 275 | [self bottom:bottomValue FromView:view]; 276 | } 277 | 278 | - (void)leftRatio:(CGFloat)left FromView:(UIView *)view screenType:(UIScreenType)screenType 279 | { 280 | CGFloat leftRatio = left / screenType; 281 | CGFloat leftValue = leftRatio * self.superview.ct_width; 282 | [self left:leftValue FromView:view]; 283 | } 284 | 285 | - (void)rightRatio:(CGFloat)right FromView:(UIView *)view screenType:(UIScreenType)screenType 286 | { 287 | CGFloat rightRatio = right / screenType; 288 | CGFloat rightValue = rightRatio * self.superview.ct_width; 289 | [self right:rightValue FromView:view]; 290 | } 291 | 292 | - (void)topInContainer:(CGFloat)top shouldResize:(BOOL)shouldResize 293 | { 294 | if (shouldResize) { 295 | self.ct_height = self.ct_y - top + self.ct_height; 296 | } 297 | self.ct_y = top; 298 | } 299 | 300 | - (void)bottomInContainer:(CGFloat)bottom shouldResize:(BOOL)shouldResize 301 | { 302 | if (shouldResize) { 303 | self.ct_height = self.superview.ct_height - bottom - self.ct_y - self.safeAreaBottomGap; 304 | } else { 305 | self.ct_y = self.superview.ct_height - self.ct_height - bottom - self.safeAreaBottomGap; 306 | } 307 | } 308 | 309 | - (void)leftInContainer:(CGFloat)left shouldResize:(BOOL)shouldResize 310 | { 311 | if (shouldResize) { 312 | self.ct_width = self.ct_x - left + self.ct_width; 313 | } 314 | self.ct_x = left; 315 | } 316 | 317 | - (void)rightInContainer:(CGFloat)right shouldResize:(BOOL)shouldResize 318 | { 319 | if (shouldResize) { 320 | self.ct_width = self.superview.ct_width - right - self.ct_x; 321 | } else { 322 | self.ct_x = self.superview.ct_width - self.ct_width - right; 323 | } 324 | } 325 | 326 | - (void)topRatioInContainer:(CGFloat)top shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType 327 | { 328 | CGFloat topRatio = top / screenType; 329 | CGFloat topValue = topRatio * self.superview.ct_width; 330 | [self topInContainer:topValue shouldResize:shouldResize]; 331 | } 332 | 333 | - (void)bottomRatioInContainer:(CGFloat)bottom shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType 334 | { 335 | CGFloat bottomRatio = bottom / screenType; 336 | CGFloat bottomValue = bottomRatio * self.superview.ct_width; 337 | [self bottomInContainer:bottomValue shouldResize:shouldResize]; 338 | } 339 | 340 | - (void)leftRatioInContainer:(CGFloat)left shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType 341 | { 342 | CGFloat leftRatio = left / screenType; 343 | CGFloat leftValue = leftRatio * self.superview.ct_width; 344 | [self leftInContainer:leftValue shouldResize:shouldResize]; 345 | } 346 | 347 | - (void)rightRatioInContainer:(CGFloat)right shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType 348 | { 349 | CGFloat rightRatio = right / screenType; 350 | CGFloat rightValue = rightRatio * self.superview.ct_width; 351 | [self rightInContainer:rightValue shouldResize:shouldResize]; 352 | } 353 | 354 | - (void)topEqualToView:(UIView *)view 355 | { 356 | UIView *superView = view.superview ? view.superview : view; 357 | CGPoint viewOrigin = [superView convertPoint:view.ct_origin toView:self.topSuperView]; 358 | CGPoint newOrigin = [self.topSuperView convertPoint:viewOrigin toView:self.superview]; 359 | 360 | self.ct_y = newOrigin.y; 361 | } 362 | 363 | - (void)bottomEqualToView:(UIView *)view 364 | { 365 | UIView *superView = view.superview ? view.superview : view; 366 | CGPoint viewOrigin = [superView convertPoint:view.ct_origin toView:self.topSuperView]; 367 | CGPoint newOrigin = [self.topSuperView convertPoint:viewOrigin toView:self.superview]; 368 | 369 | self.ct_y = newOrigin.y + view.ct_height - self.ct_height; 370 | } 371 | 372 | - (void)leftEqualToView:(UIView *)view 373 | { 374 | UIView *superView = view.superview ? view.superview : view; 375 | CGPoint viewOrigin = [superView convertPoint:view.ct_origin toView:self.topSuperView]; 376 | CGPoint newOrigin = [self.topSuperView convertPoint:viewOrigin toView:self.superview]; 377 | 378 | self.ct_x = newOrigin.x; 379 | } 380 | 381 | - (void)rightEqualToView:(UIView *)view 382 | { 383 | UIView *superView = view.superview ? view.superview : view; 384 | CGPoint viewOrigin = [superView convertPoint:view.ct_origin toView:self.topSuperView]; 385 | CGPoint newOrigin = [self.topSuperView convertPoint:viewOrigin toView:self.superview]; 386 | 387 | self.ct_x = newOrigin.x + view.ct_width - self.ct_width; 388 | } 389 | 390 | // size 391 | - (void)setCt_size:(CGSize)size 392 | { 393 | self.frame = CGRectMake(self.ct_x, self.ct_y, size.width, size.height); 394 | } 395 | 396 | - (void)setSize:(CGSize)size screenType:(UIScreenType)screenType 397 | { 398 | CGFloat ratio = SCREEN_WIDTH / screenType; 399 | self.frame = CGRectMake(self.ct_x, self.ct_y, size.width * ratio, size.height * ratio); 400 | } 401 | 402 | - (void)sizeEqualToView:(UIView *)view 403 | { 404 | self.frame = CGRectMake(self.ct_x, self.ct_y, view.ct_width, view.ct_height); 405 | } 406 | 407 | // imbueset 408 | - (void)fillWidth 409 | { 410 | self.ct_width = self.superview.ct_width; 411 | self.ct_x = 0; 412 | } 413 | 414 | - (void)fillHeight 415 | { 416 | self.ct_height = self.superview.ct_height; 417 | self.ct_y = 0; 418 | } 419 | 420 | - (void)fill 421 | { 422 | self.frame = CGRectMake(0, 0, self.superview.ct_width, self.superview.ct_height); 423 | } 424 | 425 | - (UIView *)topSuperView 426 | { 427 | UIView *topSuperView = self.superview; 428 | 429 | if (topSuperView == nil) { 430 | topSuperView = self; 431 | } else { 432 | while (topSuperView.superview) { 433 | topSuperView = topSuperView.superview; 434 | } 435 | } 436 | 437 | return topSuperView; 438 | } 439 | 440 | // iPhoneX adapt 441 | - (CGFloat)safeAreaBottomGap 442 | { 443 | NSNumber *gap = objc_getAssociatedObject(self, kUIViewLayoutMethodPropertyBottomGap); 444 | if (gap == nil) { 445 | if (@available(iOS 11, *)) { 446 | if (self.superview.safeAreaLayoutGuide.layoutFrame.size.height > 0) { 447 | gap = @((self.superview.ct_height - self.superview.safeAreaLayoutGuide.layoutFrame.origin.y - self.superview.safeAreaLayoutGuide.layoutFrame.size.height)); 448 | } else { 449 | gap = nil; 450 | } 451 | } else { 452 | gap = @(0); 453 | } 454 | objc_setAssociatedObject(self, kUIViewLayoutMethodPropertyBottomGap, gap, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 455 | } 456 | return gap.floatValue; 457 | } 458 | 459 | - (CGFloat)safeAreaTopGap 460 | { 461 | NSNumber *gap = objc_getAssociatedObject(self, kUIViewLayoutMethodPropertyTopGap); 462 | if (gap == nil) { 463 | if (@available(iOS 11, *)) { 464 | gap = @(self.superview.safeAreaLayoutGuide.layoutFrame.origin.y); 465 | } else { 466 | gap = @(0); 467 | } 468 | objc_setAssociatedObject(self, kUIViewLayoutMethodPropertyTopGap, gap, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 469 | } 470 | return gap.floatValue; 471 | } 472 | 473 | - (CGFloat)safeAreaLeftGap 474 | { 475 | NSNumber *gap = objc_getAssociatedObject(self, kUIViewLayoutMethodPropertyLeftGap); 476 | if (gap == nil) { 477 | if (@available(iOS 11, *)) { 478 | gap = @(self.superview.safeAreaLayoutGuide.layoutFrame.origin.x); 479 | } else { 480 | gap = @(0); 481 | } 482 | objc_setAssociatedObject(self, kUIViewLayoutMethodPropertyLeftGap, gap, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 483 | } 484 | return gap.floatValue; 485 | } 486 | 487 | - (CGFloat)safeAreaRightGap 488 | { 489 | NSNumber *gap = objc_getAssociatedObject(self, kUIViewLayoutMethodPropertyRightGap); 490 | if (gap == nil) { 491 | if (@available(iOS 11, *)) { 492 | gap = @(self.superview.safeAreaLayoutGuide.layoutFrame.origin.x); 493 | } else { 494 | gap = @(0); 495 | } 496 | objc_setAssociatedObject(self, kUIViewLayoutMethodPropertyRightGap, gap, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 497 | } 498 | return gap.floatValue; 499 | } 500 | 501 | @end 502 | --------------------------------------------------------------------------------