「OC」UI學習筆記(二)
文章目錄
- 「OC」UI學習筆記(二)
- 手動布局子視圖
- 自動布局子視圖
- 導航控制器
- 高級使用
手動布局子視圖
//父視圖的.h文件
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN@interface JCSuperView : UIView
{UIView *_v1;UIView *_v2;UIView *_v3;UIView *_v4;
}
-(void)makeView;
@endNS_ASSUME_NONNULL_END
—————————————————————————————————————————————————————————————————————————————————————————————————————————
//父視圖.m文件內容
#import "JCSuperView.h"@implementation JCSuperView//布局父視圖
-(void)makeView {//左上角_v1 = [[UIView alloc] init];_v1.frame = CGRectMake(0, 0, 40, 40);//右上角_v2 = [[UIView alloc] init];_v2.frame = CGRectMake(self.bounds.size.width - 40, 0, 40, 40);//右下角_v3 = [[UIView alloc] init];_v3.frame = CGRectMake(self.bounds.size.width - 40, self.bounds.size.height - 40, 40, 40);//左下角_v4 = [[UIView alloc] init];_v4.frame = CGRectMake(0, self.bounds.size.height - 40, 40, 40);_v1.backgroundColor = [UIColor redColor];_v2.backgroundColor = [UIColor redColor];_v3.backgroundColor = [UIColor redColor];_v4.backgroundColor = [UIColor redColor];[self addSubview:_v1];[self addSubview:_v2];[self addSubview:_v3];[self addSubview:_v4];}
//當需要重新布局時會調用此函數
-(void)layoutSubviews {[UIView beginAnimations:nil context:nil];[UIView setAnimationDuration:1];_v1.frame = CGRectMake(0, 0, 40, 40);_v2.frame = CGRectMake(self.bounds.size.width - 40, 0, 40, 40);_v3.frame = CGRectMake(self.bounds.size.width - 40, self.bounds.size.height - 40, 40, 40);_v4.frame = CGRectMake(0, self.bounds.size.height - 40, 40, 40);[UIView commitAnimations];
}@end
—————————————————————————————————————————————————————————————————————————————————————————————————————————
#import <UIKit/UIKit.h>
#import "ViewController.h"
#import "JCViewViewController.h"
#import "JCSuperView.h"@interface ViewController ()@end@implementation ViewController//在第一次加載被使用
- (void)viewDidLoad {[super viewDidLoad];[self makeSuper];
}-(void)makeSuper {JCSuperView *superview = [[JCSuperView alloc] initWithFrame:CGRectMake(20, 20, 200, 300)];[superview makeView];superview.backgroundColor = [UIColor greenColor];superview.tag = 101;UIButton *b1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];b1.frame = CGRectMake(300, 600, 80, 40);[b1 setTitle:@"放大" forState:UIControlStateNormal];[b1 addTarget:self action:@selector(beBig) forControlEvents:UIControlEventTouchUpInside];UIButton *b2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];b2.frame = CGRectMake(300, 700, 80, 40);[b2 setTitle:@"縮小" forState:UIControlStateNormal];[b2 addTarget:self action:@selector(beSmall) forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:superview];[self.view addSubview: b1];[self.view addSubview: b2];
}//事件放大功能
-(void)beBig {JCSuperView *sview = (JCSuperView*)[self.view viewWithTag:101];[UIView beginAnimations:nil context:nil];[UIView setAnimationDuration:1];sview.frame = CGRectMake(50, 50, 300, 400);[UIView commitAnimations];
}//實現縮小功能
-(void)beSmall {JCSuperView *sview = (JCSuperView*)[self.view viewWithTag:101];[UIView beginAnimations:nil context:nil];[UIView setAnimationDuration:1];sview.frame = CGRectMake(50, 50, 200, 300);[UIView commitAnimations];
}
自動布局子視圖
-(void)makeAutoView {_sview = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 180, 280)];_sview.backgroundColor = [UIColor blueColor];_v1 = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];_v1.backgroundColor = [UIColor redColor];_v1.text = @"1";_v2 = [[UILabel alloc] initWithFrame:CGRectMake(140, 0, 40, 40)];_v2.backgroundColor = [UIColor redColor];_v2.text = @"2";_v3 = [[UILabel alloc] initWithFrame:CGRectMake(140, 240, 40, 40)];_v3.backgroundColor = [UIColor redColor];_v3.text = @"3";_v4 = [[UILabel alloc] initWithFrame:CGRectMake(0, 240, 40, 40)];_v4.backgroundColor = [UIColor redColor];_v4.text = @"4";[_sview addSubview:_v1];[_sview addSubview:_v2];[_sview addSubview:_v3];[_sview addSubview:_v4];[self.view addSubview:_sview];_center = [[UIView alloc]initWithFrame:CGRectMake(0, 0, _sview.bounds.size.width, 40)];_center.center = CGPointMake(90, 140);_center.backgroundColor = [UIColor redColor];[_sview addSubview:_center];//自動布局屬性,設置子視圖和父視圖的相對關系_center.autoresizingMask = UIViewAutoresizingFlexibleWidth| UIViewAutoresizingFlexibleTopMargin| UIViewAutoresizingFlexibleBottomMargin;//設置左邊為可變距離_v2.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;_v3.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin;_v4.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {static BOOL flag = NO;[UIView beginAnimations:nil context:nil];[UIView setAnimationDuration:1];if (flag == NO) {_sview.frame = CGRectMake(20, 20, 360, 480);flag = YES;} else {_sview.frame = CGRectMake(20, 20, 180, 280);flag = NO;}[UIView commitAnimations];
}
在iOS13.0版本中beginAnimations
和commitAnimations
方法已經被廢棄,不推薦在新的iOS開發中使用。現在的iOS開發更常用的是使用UIView
的動畫塊(animateWithDuration:animations:
)或UIViewPropertyAnimator
等更高級的API來實現動畫效果。這些新的API提供了更靈活、更強大的動畫控制能力,并提供了更好的性能和可讀性。
以下是對上面程序使用animateWithDuration:animations:
進行改寫
-(void)makeAutoView {_sview = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 180, 280)];_sview.backgroundColor = [UIColor blueColor];_v1 = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];_v1.backgroundColor = [UIColor redColor];_v1.text = @"1";_v2 = [[UILabel alloc] initWithFrame:CGRectMake(140, 0, 40, 40)];_v2.backgroundColor = [UIColor redColor];_v2.text = @"2";_v3 = [[UILabel alloc] initWithFrame:CGRectMake(140, 240, 40, 40)];_v3.backgroundColor = [UIColor redColor];_v3.text = @"3";_v4 = [[UILabel alloc] initWithFrame:CGRectMake(0, 240, 40, 40)];_v4.backgroundColor = [UIColor redColor];_v4.text = @"4";[_sview addSubview:_v1];[_sview addSubview:_v2];[_sview addSubview:_v3];[_sview addSubview:_v4];[self.view addSubview:_sview];_center = [[UIView alloc]initWithFrame:CGRectMake(0, 0, _sview.bounds.size.width, 40)];_center.center = CGPointMake(90, 140);_center.backgroundColor = [UIColor redColor];[_sview addSubview:_center];//自動布局屬性,設置子視圖和父視圖的相對關系_center.autoresizingMask = UIViewAutoresizingFlexibleWidth| UIViewAutoresizingFlexibleTopMargin| UIViewAutoresizingFlexibleBottomMargin;//設置左邊為可變距離_v2.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;_v3.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin;_v4.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {static BOOL flag = NO;//參數一:動畫時長//參數二:代碼塊實現功能[UIView animateWithDuration:1 animations:^{if (flag == NO) {self->_sview.frame = CGRectMake(20, 20, 360, 480);flag = YES;} else {self->_sview.frame = CGRectMake(20, 20, 180, 280);flag = NO;}}];
}
導航控制器
//SceneDelegate.m
#import "SceneDelegate.h"
#import "ViewController.h"
#import "JCRootViewController.h"
@interface SceneDelegate ()@end@implementation SceneDelegate- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {self.window.frame = [UIScreen mainScreen].bounds;//創建視圖控制器JCRootViewController *root = [[JCRootViewController alloc] init];//創建導航控制器——主要用于管理多個視圖控制器的切換//在創建控制器,一定要有一個根視圖控制器//參數一:就是作為導航控制器的根視圖控制器UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:root];//將根視圖設置為導航控制器self.window.rootViewController = nav;[self.window makeKeyAndVisible];}- (void)sceneDidDisconnect:(UIScene *)scene {// Called as the scene is being released by the system.// This occurs shortly after the scene enters the background, or when its session is discarded.// Release any resources associated with this scene that can be re-created the next time the scene connects.// The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
}- (void)sceneDidBecomeActive:(UIScene *)scene {// Called when the scene has moved from an inactive state to an active state.// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}- (void)sceneWillResignActive:(UIScene *)scene {// Called when the scene will move from an active state to an inactive state.// This may occur due to temporary interruptions (ex. an incoming phone call).
}- (void)sceneWillEnterForeground:(UIScene *)scene {// Called as the scene transitions from the background to the foreground.// Use this method to undo the changes made on entering the background.
}- (void)sceneDidEnterBackground:(UIScene *)scene {// Called as the scene transitions from the foreground to the background.// Use this method to save data, release shared resources, and store enough scene-specific state information// to restore the scene back to its current state.
}@end
—————————————————————————————————————————————————————————————————————————————————————————————————————————
//創建一個新的controller的子類,作為新的主根視圖
#import"JCRootViewController.h"@interface JCRootViewController ()@end@implementation JCRootViewController- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.self.view.backgroundColor = [UIColor yellowColor];//設置導航欄文字self.title = @"根視圖";//設置導航元素項目標題self.navigationItem.title = @"Title";//優先使用title為標題//只能指定風格樣式,系統風格的按鈕內容或者標題字體不能改變UIBarButtonItem *left = [[UIBarButtonItem alloc] initWithTitle:@"回退" style:UIBarButtonItemStyleDone target:self action:@selector(pressLeft)];//向導航欄左側的按鈕進行賦值self.navigationItem.leftBarButtonItem = left;UIBarButtonItem *right = [[UIBarButtonItem alloc] initWithTitle:@"詳情" style:UIBarButtonItemStylePlain target:self action:@selector(pressRight)];//向導航欄右側的按鈕進行賦值self.navigationItem.rightBarButtonItem = right;//添加多個按鈕,將多個控件添加至導航欄右側之中UILabel *l = [[UILabel alloc] init];l.text = @"test";l.textAlignment = NSTextAlignmentCenter;UIBarButtonItem *btn = [[UIBarButtonItem alloc] initWithCustomView:l];NSArray *arr = [NSArray arrayWithObjects:btn, right, nil];self.navigationItem.rightBarButtonItems = arr;
}-(void)pressLeft {NSLog(@"回退鍵被點擊");
}
-(void)pressRight {NSLog(@"詳情鍵被點擊");
}
/*
#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.
}
*/@end
高級使用
//SceneDelegate.m
#import "SceneDelegate.h"
#import "FirstViewController.h"
#import "SecondViewController.h"
#import "ThirdViewController.h"
#import "fourthViewController.h"
#import "fifthViewController.h"
#import "sixthViewController.h"
@interface SceneDelegate ()@end@implementation SceneDelegate- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {_window.frame = [UIScreen mainScreen].bounds;// 創建視圖控制器FirstViewController *v1 = [[FirstViewController alloc] init];SecondViewController *v2 = [[SecondViewController alloc] init];ThirdViewController *v3 = [[ThirdViewController alloc] init];fourthViewController *v4 = [[fourthViewController alloc] init];fifthViewController *v5 = [[fifthViewController alloc] init];sixthViewController *v6 = [[sixthViewController alloc] init];// 創建 UITabBarController 并設置視圖控制器數組UITabBarController *tabBarController = [[UITabBarController alloc] init];//通過edit修改會修改數組之中元素的順序tabBarController.viewControllers = @[v1, v2, v3, v4, v5, v6];// 設置每個選項卡的標題v1.title = @"Tab 1";v2.title = @"Tab 2";v3.title = @"Tab 3";v4.title = @"Tab 4";v5.title = @"Tab 5";v6.title = @"Tab 6";// 將每個視圖控制器設置不同的背景顏色v1.view.backgroundColor = [UIColor redColor];v2.view.backgroundColor = [UIColor blueColor];v3.view.backgroundColor = [UIColor greenColor];v4.view.backgroundColor = [UIColor yellowColor];v5.view.backgroundColor = [UIColor purpleColor];v6.view.backgroundColor = [UIColor orangeColor];//導航欄顏色tabBarController.tabBar.barTintColor = [UIColor whiteColor];//改變按鈕風格顏色tabBarController.tabBar.tintColor = [UIColor blackColor];// 將導航控制器設置為根視圖控制器_window.rootViewController = tabBarController;//設置代理tabBarController.delegate = self;[_window makeKeyAndVisible];
}//即將開始編輯時調用
-(void)tabBarController:(UITabBarController *)tabBarController willBeginCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers {NSLog(@"編輯之前");
}//即將結束編輯之時
-(void)tabBarController:(UITabBarController *)tabBarController willEndCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers changed:(BOOL)changed {NSLog(@"即將結束");
}-(void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers changed:(BOOL)changed {NSLog(@"已經結束編輯");
}-(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {NSLog(@"選中后控制器對象 —— %lu",(unsigned long)tabBarController.selectedIndex);
}- (void)sceneDidDisconnect:(UIScene *)scene {// Called as the scene is being released by the system.// This occurs shortly after the scene enters the background, or when its session is discarded.// Release any resources associated with this scene that can be re-created the next time the scene connects.// The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
}- (void)sceneDidBecomeActive:(UIScene *)scene {// Called when the scene has moved from an inactive state to an active state.// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}- (void)sceneWillResignActive:(UIScene *)scene {// Called when the scene will move from an active state to an inactive state.// This may occur due to temporary interruptions (ex. an incoming phone call).
}- (void)sceneWillEnterForeground:(UIScene *)scene {// Called as the scene transitions from the background to the foreground.// Use this method to undo the changes made on entering the background.
}- (void)sceneDidEnterBackground:(UIScene *)scene {// Called as the scene transitions from the foreground to the background.// Use this method to save data, release shared resources, and store enough scene-specific state information// to restore the scene back to its current state.
}@end