UIKit-基础
App
当在AppDelegate生命周期内,如果出现新的窗口被请求的时候会自动调用AppDelegate的configurationForConnectingSceneSession方法对新的UIScene进行配置,同时就会创建新的SceneDelegate,在SceneDelegate被创建后就会调用SceneDelegate的willConnectToSession方法,这个方法可以选择性配置创建的UIWindow,然后将UIScene和UIWindow连接上,如果使用了storyboard则这个window的属性也会自动被初始化和连接到scene上。
当scene进入后台或者被丢弃时会调用sceneDidDisconnect,会释放任何和scene有关的资源,这些资源可以在下次scene重新连接的时候重新创建
sendAction:to:from:forEvent:
一般是在UIControl对象被touch的时候调用,会dispatch一个action method
给目标对象 如果没有特殊指定对象就会发给first responder,所以Application是继承自UIControl 是会自动调用的
实际上这个就是底层实现,
比如说你添加了一个button,然后添加在view上,给这个button添加了一个action叫btnAction,则当你点击button的时候会先执行 sendAction:btnAction to:view sender:button event:UITouchEvent
然后 就调用btnAction
注意
如果你要动态替换掉sendAction方法你需要在重写方法里面再添加一次 主要是因为原方法和新方法做了替换,所以先调用原方法的时候因为替换 调用的是新方法,然后在新方法里面调用了新方法(由于替换 调用的是原方法)
创建UIApplication + extern.m
#import "UIApplication + extern.h"
#import
#import @implementation UIApplication(AppExtern)//自动调用 在加载app的时候会调用
+ (void)load {NSLog(@"%s",__func__);[self test_swizzleMethod:@selector(sendAction:to:from:forEvent:) withMethod:@selector(test_sendAction:to:from:forEvent:) error:nil];
}//将使用test_sendAction动态替换sendAction 注意 这个方法里面重复调用了test_sendAction,原因是将test_sendAction和sendAction做了交换,首先是系统自动调用sendAction(由于做了交换 所以第一次实际上调用的是test_sendAction),然后在test_sendAction里面调用test_sendAction(由于做了交换,此时实际上调用的是sendAction)
- (void)test_sendAction:(SEL)action to:(id)target from:(id)sender forEvent:(UIEvent *)event
{NSLog(@"%s",__func__);[self test_sendAction:action to:target from:sender forEvent:event];
}//动态替换方法
+ (BOOL)test_swizzleMethod:(SEL)origSel_ withMethod:(SEL)altSel_ error:(NSError**)error_ {Method origMethod = class_getInstanceMethod(self, origSel_);if (!origMethod) {NSLog(@"original method %@ not found for class %@", NSStringFromSelector(origSel_), [self class]);return NO;}Method altMethod = class_getInstanceMethod(self, altSel_);if (!altMethod) {NSLog(@"alternate method %@ not found for class %@", NSStringFromSelector(altSel_), [self class]);return NO;}class_addMethod(self,origSel_,class_getMethodImplementation(self, origSel_),method_getTypeEncoding(origMethod));class_addMethod(self,altSel_,class_getMethodImplementation(self, altSel_),method_getTypeEncoding(altMethod));method_exchangeImplementations(class_getInstanceMethod(self, origSel_), class_getInstanceMethod(self, altSel_));return YES;
}
@end
storyboard
想要指定storyboard显示的view 目前还没确定
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];UIViewController *rootViewController = [storyboard instantiateInitialViewController];
instantiateInitialViewController这个方法会自动创建并返回 storyboard 文件中的第一个视图控制器,要求 storyboard 文件中必须有一个标记为 “Is Initial View Controller” 的视图控制器。这个属性可以在 storyboard 中的视图控制器属性检查器中进行设置。如果 storyboard 中没有设置初始视图控制器,或者设置了多个初始视图控制器,那么 instantiateInitialViewController 方法将返回 nil
UIWindowSceneDelegate
这个协议里面约定了一定有一个window属性,所以在创建新项目时系统自动创建的SceneDelegate里面会自带@property (strong, nonatomic) UIWindow * window;
这个也没办法改名,比如改成mainWindow都是不行的,所以应该是改不了这个window,默认就是用这个
UINavigation
相当于一个viewController的stack,用于管理view的显示。在window连接了一个NavigationController后会显示堆顶的viewController的view。所以如果要显示一个view就push进去,不要了就pop出来
显示View的方法
presentViewController,这种方法如果显示动画 view是从下往上显示出来的
pushViewController 是从右往左显示出来
创建时必须要有一个viewController作为rootViewController。
视图位移
其他还有缩放和旋转
self.btn.transform = CGAffineTransformTranslate(self.btn.transform,20, 20);//以btn当前位置做偏移 可以连续偏移的
self.btn.transform = CGAffineTransformEqualToTransform(20, 20);//偏移到指定位置
self.btn.transform = CGAffineTransformIdentity;//清空之前的操作
scene
Application Session Role
一是般填在plist里面
UIWindowSceneSessionRoleApplication://表示应用程序场景是主要的应用程序场景,用于承载应用程序的主要用户界面。
UIWindowSceneSessionRoleExternalDisplay://表示应用程序场景用于外部显示,如外接显示器或投影仪等。
UIWindowSceneSessionRoleAssistant://表示应用程序场景用于显示助理界面,例如 Siri 提示、CarPlay 等。
UIWindowSceneSessionRolePresentation://表示应用程序场景用于呈现其他内容,例如弹出式菜单、通知中心等。
如果在这个plist里面添加了Storyboard Name -> Main
表示启用Main.storyBoard,则window的属性会被自动除时候,并且连接到当前的scene上 也就是相关的SceneDelegate的scene上
如果不想用storyboard那就必须手动代码创建一个window
//sceneDelegate.m
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {NSLog(@"%s",__FUNCTION__);self.customVC = [[customVCViewController alloc]init];UINavigationController *nv = [[UINavigationController alloc]initWithRootViewController:self.customVC];float width = [UIScreen mainScreen].bounds.size.width;float height = [UIScreen mainScreen].bounds.size.height;self.window = [[UIWindow alloc]initWithWindowScene:(UIWindowScene *)scene];self.window.rootViewController = nv;// 设置窗口可见[self.window makeKeyAndVisible];// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
}
UIViewController
如果UIViewController不关联xib文件,UIViewController在init的时候会自动创建一个view
如果你想让VC去管理自定义的view可以在- (void)loadView
里面添加自定义的view 但是这个view必须自己实现相关的设置比如说在view init的时候要设置相应的约束或者rect等等。
viewController的 view 属性被首次访问时,系统会调用 loadView 方法来加载view并将其赋值给 view 属性。
一般是系统自动调用 然后创建UIView作为viewController.view的值,但是当你想加载自定义view的时候就需要在这里将view更改为自定义view
- (void)loadView
{customView* customV = [[customView alloc]init];self.view = customV;
}
原先添加viewController.view上面的subView是在viewController的viewDidLoad里面添加,但是如果自定义了view,那就是在view的init里面可以添加
UITapGestureRecognizer(手势识别器(gesture recognizer))
可以识别用户对该视图进行的单次或多次轻触操作。当手势被识别时,可以触发相应的操作或调用指定的处理方法。
// 创建一个 UITapGestureRecognizer 对象
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];// 设置手势的属性(可选)
tapGesture.numberOfTapsRequired = 1; // 单击次数要求
tapGesture.numberOfTouchesRequired = 1; // 手指数量要求// 将手势添加到视图上
[self.view addGestureRecognizer:tapGesture];// 处理手势的方法
- (void)handleTap:(UITapGestureRecognizer *)gesture {// 在此处执行相应的操作NSLog(@"Tap gesture recognized");
}
标签:
相关文章
-
无相关信息