开发细节(二)
1. 利用Auto Layout整体排列控件
下面的代码演示了一个控件如何在其父容器中垂直水平居中:
UIView *box = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 200, 150)]; box.backgroundColor = [UIColor grayColor]; [self.view addSubview:box]; UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [button setTitle:@"a button" forState:UIControlStateNormal]; [button sizeToFit]; button.translatesAutoresizingMaskIntoConstraints = NO; [box addSubview:button]; NSMutableArray *array = [[NSMutableArray alloc] init]; [array addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[box]-(<=1)-[button]" options:NSLayoutFormatAlignAllCenterX metrics:nil views:NSDictionaryOfVariableBindings(box,button)]]; [array addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[box]-(<=1)-[button]" options:NSLayoutFormatAlignAllCenterY metrics:nil views:NSDictionaryOfVariableBindings(box,button)]]; [box addConstraints:array];
下面的代码演示了多个控件其父容器中水平左对齐,垂直居中:
UIView *box = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 200, 150)]; box.backgroundColor = [UIColor grayColor]; [self.view addSubview:box]; UILabel *label = [[UILabel alloc] init]; label.text = @"a label"; [label sizeToFit]; label.backgroundColor = [UIColor redColor]; label.translatesAutoresizingMaskIntoConstraints = NO; [box addSubview:label]; UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [button setTitle:@"a button" forState:UIControlStateNormal]; [button sizeToFit]; button.translatesAutoresizingMaskIntoConstraints = NO; [box addSubview:button]; NSMutableArray *array = [[NSMutableArray alloc] init]; [array addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[button]-|" options:NSLayoutFormatAlignAllLeft metrics:nil views:NSDictionaryOfVariableBindings(button)]]; [array addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"|-15-[myLabel]-5-[myButton]" options:NSLayoutFormatAlignAllCenterY metrics:nil views:@{@"myLabel":label, @"myButton":button}]]; [box addConstraints:array];
2. ScrollView利用Auto Layout管理控件
3. IB_DESIGNABLE,IBInspectable配合XIB实现自定义控件
#import <UIKit/UIKit.h> @interface MyTempView : UIView @property (weak, nonatomic) IBOutlet UIView *contentView; @property (weak, nonatomic) IBOutlet UILabel *myLabel; @end
#import "MyTempView.h" IB_DESIGNABLE @interface MyTempView () @property (nonatomic) IBInspectable NSString *myText; @end @implementation MyTempView - (void)setMyText:(NSString *)myText { self.myLabel.text = myText; } - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self commonSetup]; } return self; } - (instancetype)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { [self commonSetup]; } return self; } - (UIView *)loadViewFromNib { NSBundle *bundle = [NSBundle bundleForClass:[self class]]; //xib文件名与类文件名不同 // UIView *view = [[bundle loadNibNamed:@"abc" owner:self options:nil] firstObject]; //xib文件名与类文件名相同 UIView *view = [[bundle loadNibNamed:NSStringFromClass([self class]) owner:self options:nil] firstObject]; return view; } - (void)commonSetup { UIView *nibView = [self loadViewFromNib]; nibView.frame = self.bounds; // the autoresizingMask will be converted to constraints, the frame will match the parent view frame nibView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; // Adding nibView on the top of our view [self addSubview:nibView]; } @end
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10116" systemVersion="15E65" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES"> <dependencies> <deployment identifier="iOS"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/> </dependencies> <objects> <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="MyTempView"> <connections> <outlet property="contentView" destination="iN0-l3-epB" id="a2U-Rp-jYq"/> <outlet property="myLabel" destination="IIE-8B-dDU" id="mM8-Li-TQ0"/> </connections> </placeholder> <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> <view contentMode="scaleToFill" id="iN0-l3-epB"> <rect key="frame" x="0.0" y="0.0" width="600" height="600"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="IIE-8B-dDU"> <rect key="frame" x="27" y="32" width="162" height="21"/> <fontDescription key="fontDescription" name="HelveticaNeue" family="Helvetica Neue" pointSize="17"/> <color key="textColor" cocoaTouchSystemColor="darkTextColor"/> <nil key="highlightedColor"/> </label> </subviews> <color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/> </view> </objects> </document>
4. 自定义控件利用delegate触发事件
#import "ViewController.h" #import "MyView.h" @interface ViewController () <MyDelegate> @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; MyView *view1 = [[MyView alloc] initWithFrame:CGRectMake(30, 30, 250, 300)]; view1.backgroundColor = [UIColor greenColor]; view1.delegate = self; [self.view addSubview:view1]; } - (void)eat:(NSString *)food { NSLog(@"wayne eat %@", food); } - (void)read:(NSString *)book { NSLog(@"wayne read a book called %@", book); } @end
#import <UIKit/UIKit.h> @protocol MyDelegate <NSObject,UICollectionViewDelegate> @optional - (void)sing:(NSString *)song; - (void)read:(NSString *)book; @required - (void)eat:(NSString *)food; @end @interface MyView : UIView @property (nonatomic, weak) id <MyDelegate> delegate; @end
#import "MyView.h" @implementation MyView - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if(self) { [self initDataAndUI]; } return self; } - (void)initDataAndUI { UIButton *firstButton = [UIButton buttonWithType:UIButtonTypeCustom]; [firstButton setTitle:@"Eat Button" forState:UIControlStateNormal]; [firstButton setBackgroundColor:[UIColor purpleColor]]; [firstButton sizeToFit]; [firstButton addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:firstButton]; } - (void)buttonClicked:(id)sender { [(id<MyDelegate>)self.delegate eat:@"an apple"]; [self.delegate read:@"Robinson Crusoe"]; } @end
5. NSJSONSerialization的NSJSONReadingOptions参数
NSJSONReadingMutableContainers -- 返回可变容器,NSMutableDictionary或NSMutableArray
NSJSONReadingMutableLeaves -- 返回的JSON对象中字符串的值为NSMutableString
NSJSONReadingAllowFragments -- 允许JSON字符串最外层既不是NSArray也不是NSDictionary,但必须是有效的JSON Fragment
kNilOptions -- 不设置该参数,返回不可变的NSDictionary
NSString *str = @"{\"name\":\"wayne\"}"; //设置为kNilOptions后尝试修改字典内容,会导致报错 //NSMutableDictionary *dict = [NSJSONSerialization JSONObjectWithData:[str dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:nil]; NSMutableDictionary *dict = [NSJSONSerialization JSONObjectWithData:[str dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:nil]; [dict setObject:@"tom" forKey:@"name"]; NSLog(@"dict= %@,type= %@",dict,[dict class]);
NSString *num=@"32"; //ok num = @"ABC"; //error num = @"\"ABC\""; //ok NSError *error; NSData *createdData = [num dataUsingEncoding:NSUTF8StringEncoding]; id response=[NSJSONSerialization JSONObjectWithData:createdData options:NSJSONReadingAllowFragments error:&error]; NSLog(@"Response= %@,type= %@",response,[response class]);
6. 一个嵌套JSON解析
NSString *jsonString = @"{\"Products\":[{\"Appliances\": {\"TV\": {\"SONY\":{\"ProductName\":\"SONY G9\", \"Size\":\"48 inch\"}, \"LETV\":{\"ProductName\":\"S50 Air\", \"Size\":\"50 inch\"} }}}, {\"Digital\": {\"Camera\": {\"Canon\":{\"ProductName\":\"EOS 70D\", \"pixel\":\"2020\"}}}}]}"; NSError *error; NSDictionary *json = [NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&error]; NSLog(@"JSON:%@",json); if (json) { NSArray *products = [json objectForKey:@"Products"]; NSDictionary *appliancesDict = products[0]; //Appliances NSLog(@"appliancesDict: %@",appliancesDict); NSDictionary *digitalDict = products[1]; //Digital NSLog(@"digitalDict: %@",digitalDict); NSLog(@"Digital:%@",[digitalDict objectForKey:@"Digital"]); NSLog(@"Camera:%@",[[digitalDict objectForKey:@"Digital"] objectForKey:@"Camera"]); NSLog(@"Canon:%@",[[[digitalDict objectForKey:@"Digital"] objectForKey:@"Camera"] objectForKey:@"Canon"]); NSLog(@"ProductName:%@",[[[[digitalDict objectForKey:@"Digital"] objectForKey:@"Camera"] objectForKey:@"Canon"] objectForKey:@"ProductName"]); NSLog(@"pixel:%@",[[[[digitalDict objectForKey:@"Digital"] objectForKey:@"Camera"] objectForKey:@"Canon"] objectForKey:@"pixel"]); }