Basic knowledge of IOS development-fragment 45, basic knowledge of ios-45
1: iOS SEL Summary
SEL is a method packaging. The encapsulated SEL data corresponds to the corresponding method address. You can call the method by finding the method address.
A. Method storage location
In memory, methods of each class are stored in class objects.
Each method has a SEL-type data corresponding to it.
You can find the corresponding method address based on a SEL data and call the method.
SEL Type Definition: typedef struct objc_selector * SEL
B. Create a SEL object
SEL s1 = @ selector (test1); // wrap the test1 method into a SEL object
SEL s2 = NSSelectorFromString (@ "test1"); // convert a string method to a SEL object
C. Other usage of SEL object
// Convert SEL object to NSString object
NSString * str = NSStringFromSelector (@ selector (test ));
Instance:
Person * p = [Person new]; // call the test method of object p [p primary mselector: @ selector (test)]; [person primary mselector: @ selector (test2 :) withObject: @ "input parameter"];
Person code: # import "Person. h "@ implementation Person-(void) test {NSLog (@" method of object without Parameters ");}-(void) test2 :( NSString *) str {NSLog (@ "method with parameters % @", str) ;}@ end
D: Application in Arrays
// Execute the test method for each element of an array [array makeObjectsPerformSelector: @ selector (test)]; [array makeObjectsPerformSelector: @ selector (test) withObject: @ "aaa"]; // sort an array [array sortedArrayUsingSelector: @ selector (compare :)];
E: target-action design mode for using Sel Parameters)
In the Button, we often use the following event to add code:
-(Void) addTarget :( nullable id) target action :( SEL) action forControlEvents :( UIControlEvents) controlEvents;
Instance:
# Import <UIKit/UIKit. h> @ interface TapView: UIView // target @ property (weak, nonatomic) id target; // behavior @ property (assign, nonatomic) SEL action; // custom method-(void) addCustomtarget :( id) target andAction :( SEL) action; @ end
# Import "TapView. h "@ implementation TapView // custom method-(void) addCustomtarget :( id) target andAction :( SEL) action {_ action = action; _ target = target;}-(void) touchesBegan :( NSSet <UITouch *> *) touches withEvent :( UIEvent *) event {// when the view is clicked, the target executes the action method and passes it to itself. // first, the proxy cannot be blank and the proxy (the proxy is an object !) The class contains methods and can be passed out. if (nil! = _ Target & [[_ target class] instancesRespondToSelector: _ action]) {[_ target extends mselector: _ action withObject: self];}
Another instance:
#import <Foundation/Foundation.h>#import <objc/runtime.h>#import "Debug.h" // not given; just an assert@interface NSObject (Extras)// Enforce the rule that the selector used must return void.- (void) performVoidReturnSelector:(SEL)aSelector withObject:(id)object;- (void) performVoidReturnSelector:(SEL)aSelector;@end@implementation NSObject (Extras)// Apparently the reason the regular performSelect gives a compile time warning is that the system doesn't know the return type. I'm going to (a) make sure that the return type is void, and (b) disable this warning// See http://stackoverflow.com/questions/7017281/performselector-may-cause-a-leak-because-its-selector-is-unknown- (void) checkSelector:(SEL)aSelector { // See http://stackoverflow.com/questions/14602854/objective-c-is-there-a-way-to-check-a-selector-return-value Method m = class_getInstanceMethod([self class], aSelector); char type[128]; method_getReturnType(m, type, sizeof(type)); NSString *message = [[NSString alloc] initWithFormat:@"NSObject+Extras.performVoidReturnSelector: %@.%@ selector (type: %s)", [self class], NSStringFromSelector(aSelector), type]; NSLog(@"%@", message); if (type[0] != 'v') { message = [[NSString alloc] initWithFormat:@"%@ was not void", message]; [Debug assertTrue:FALSE withMessage:message]; }}- (void) performVoidReturnSelector:(SEL)aSelector withObject:(id)object { [self checkSelector:aSelector];#pragma clang diagnostic push#pragma clang diagnostic ignored "-Warc-performSelector-leaks" // Since the selector (aSelector) is returning void, it doesn't make sense to try to obtain the return result of performSelector. In fact, if we do, it crashes the app. [self performSelector: aSelector withObject: object];#pragma clang diagnostic pop }- (void) performVoidReturnSelector:(SEL)aSelector { [self checkSelector:aSelector];#pragma clang diagnostic push#pragma clang diagnostic ignored "-Warc-performSelector-leaks" [self performSelector: aSelector];#pragma clang diagnostic pop}@end
2: proxy mode instance
# Import <UIKit/UIKit. h> @ protocol TouchViewDelegate <NSObject>-(void) changeViewColor :( UIColor *) color; @ end @ interface TouchView: UIView // declares a proxy, which complies with the TouchViewDelegate protocol, @ property (nonatomic, assign) id <TouchViewDelegate> delegate; @ end
# Import "TouchView. h "@ implementation TouchView // we still use touchesBegandian-(void) touchesBegan :( NSSet <UITouch *> *) touches withEvent :( UIEvent *) event {if (nil! = Self. delegate & [self. delegate respondsToSelector: @ selector (changeViewColor :)]) {// We will upload a color to our ViewController. [self. delegate changeViewColor: [UIColor brownColor] ;}}@ end
Code: # import "ViewController. h "# import" TouchView. h "// here ViewController must comply with the protocol .... @ interface ViewController () <TouchViewDelegate> @ property (nonatomic, strong) TouchView * touchView; @ end @ implementation ViewController-(void) viewDidLoad {[super viewDidLoad]; self. touchView = [[TouchView alloc] initWithFrame: CGRectMake (100,100,100,100)]; self. touchView. backgroundColor = [UIColor redColor]; // specifies the touchView The proxy of is ViewController. That is, it is itself ~ Self. touchView. delegate = self; [self. view addSubview: self. touchView];}-(void) changeViewColor :( UIColor *) color {// currently, the color parameter has a value, because it is uploaded on the page of TouchView. self. touchView. backgroundColor = color;} @ end
3: Bolck Application
# Import <UIKit/UIKit. h> // rename the block to MyBlocktypedef void (^ MyBlock) (NSString *); @ interface OtherViewController: UIViewController // ARC: Use strong for semantic settings @ property (nonatomic, strong) myBlock block; @ end
#import "OtherViewController.h"@interface OtherViewController ()@property(nonatomic,strong)UITextField *textField;@end@implementation OtherViewController- (void)viewDidLoad { [super viewDidLoad]; self.textField = [[UITextField alloc]initWithFrame:CGRectMake(0, 100, 414, 40)]; self.textField.backgroundColor = [UIColor lightGrayColor]; self.view.backgroundColor = [UIColor whiteColor]; [self.view addSubview: self.textField];}-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ self.block(_textField.text); [self.navigationController popViewControllerAnimated:YES];}@end
Code: OtherViewController * otherVC = [[OtherViewController alloc] init]; _ weak typeof (self) weak = self; // assign a value to the block ~ OtherVC. block = ^ (NSString * string) {weak. label. text = string ;}; [self. navigationController pushViewController: otherVC animated: YES];
4: Several triggering methods of UIButton
A. UIControlEventTouchDown
Click the left mouse button (Note: Only click)
B. UIControlEventTouchDownRepeat
Refers to the action of repeatedly clicking the left mouse button (Note: Only "Press") multiple times in a row, for example, double-clicking, three-clicking ,...... .
Note: The Event Sequence is as follows:
UIControlEventTouchDown->
(UIControlEventTouchUpInside)->
UIControlEventTouchDown->
UIControlEventTouchDownRepeat->
(UIControlEventTouchUpInside)->
UIControlEventTouchDown->
UIControlEventTouchDownRepeat->
(UIControlEventTouchUpInside)->
......
Except for the first press, each press isUIControlEventTouchDownEvent, followed byUIControlEventTouchDownRepeatEvent.
C,UIControlEventTouchDragInside
By pressing the mouse and dragging it within the control boundary.
D,UIControlEventTouchDragOutside
AndUIControlEventTouchDragInsideThe difference is that, when dragging, the mouse is out of the control boundary range.
But first, you must haveUIControlEventTouchDownEvent, and thenUIControlEventTouchDragInsideEvent, followed by anotherUIControlEventTouchDragExitThe mouse is already out of the control.UIControlEventTouchDragOutsideEvent.
The specific operation is to press the mouse in the control and drag it out of the control.
E,UIControlEventTouchDragEnter
It refers to the event generated during the drag action from outside the control boundary to the inner.
F,UIControlEventTouchDragExit
An event generated when the widget is dragged from inside to outside the control boundary.
G,UIControlEventTouchUpInside
When the mouse is raised within the control range, you must first press, that isUIControlEventTouchDownOrUIControlEventTouchDownRepeatEvent.
H,UIControlEventTouchUpOutside
When you move the cursor out of the control boundary, you must first press the mouse and then drag it out of the control, that is
UIControlEventTouchDown->
UIControlEventTouchDragInside (nItems)->
UIControlEventTouchDragExit->
UIControlEventTouchDragOutside (nItems)
The time series, and then the mouse is raised to generateUIControlEventTouchUpOutsideEvent.
5: Shut up the compiler for some warnings.
A: Method discard alarm
# Pragma clang diagnostic push # pragma clang diagnostic ignored "-Wdeprecated-declarations" // Method for warning, such as SEL [TestFlight setDeviceIdentifier: [[UIDevice currentDevice] uniqueIdentifier]; # pragma clang diagnostic pop
B: No variables are used.
#pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-variable" int a; #pragma clang diagnostic pop
6: A hexagonal, with only the click effect in the hexagonal
# Import <UIKit/UIKit. h> // hexagonal Button @ interface HexagonButton: Invalid void (^ HexagonButtonBlock) (); @ property (nonatomic, strong) UIBezierPath * path; @ property (nonatomic, strong) CAShapeLayer * maskLayer; @ property (nonatomic, strong) HexagonButtonBlock; // click an event // Add a click event NS_ASSUME_NONNULL_END @ end
# Import "HexagonButton. h "@ implementation HexagonButton-(instancetype) initWithFrame :( CGRect) frame {if ([super initWithFrame: frame]) {self. backgroundColor = [UIColor brownColor]; self. userInteractionEnabled = YES; // Add the click gesture UITapGestureRecognizer * tap = [[delealloc] initWithTarget: self action: @ selector (click :)]; [self addGestureRecognizer: tap];} return self;}-(void) layoutSubviews {[super layoutSubviews]; CGFloat SIZE = self. frame. size. width; // step 1: generate the hexagonal path CGFloat longSide = SIZE * 0.5 * cosf (M_PI * 30/180); CGFloat lateral side = SIZE * 0.5 * sin (M_PI * 30/180 ); CGFloat k = SIZE * 0.5-longSide; // move down the overall path to ensure that the hexagonal path is in the middle of the graph _ path = [UIBezierPath bezierPath]; [_ path moveToPoint: CGPointMake (0, longSide + k)]; [_ path addLineToPoint: CGPointMake (lateral side, + k)]; [_ path addLineToPoint: CGPointMake (lateral side + lateral side, k)]; [_ path addLineToPoint: CGPointMake (SIZE, longSide + k)]; [_ path addLineToPoint: CGPointMake (lateral side * 3, longSide * 2 + k)]; [_ path addLineToPoint: CGPointMake (lateral side, longSide * 2 + k)]; [_ path closePath]; // step 2: Generate mask _ maskLayer = [CAShapeLayer layer] based on the path; // _ maskLayer. position = self. center; _ maskLayer. path = [_ path CGPath]; // step 3: add the mask self. layer. mask = _ maskLayer; self. backgroundColor = [UIColor orangeColor];} // click Event-(void) click :( UITapGestureRecognizer *) tap {if (_ block) {_ block ();}} -(UIView *) hitTest :( CGPoint) point withEvent :( UIEvent *) event {// if the clicked area is within the range of the created path, if (CGPathContainsPoint (_ path. CGPath, NULL, point, NO) {return [super hitTest: point withEvent: event];} return nil ;}@ end
// Create the six-step deformation button HexagonButton * hexagonButton = [[HexagonButton alloc] initWithFrame: CGRectMake (20, 20,100,100)]; hexagonButton. center = self. view. center; hexagonButton. block = ^ () {NSLog (@ "hexagonal region clicked") ;}; [self. view addSubview: hexagonButton];