IOS開發基礎知識--片段45,ios基礎知識--45

來源:互聯網
上載者:User

IOS開發基礎知識--片段45,ios基礎知識--45

1:iOS SEL的簡單總結

SEL就是對方法的一種封裝。封裝的SEL類型資料它對應相應的方法地址,找到方法地址就可以調用方法

a.方法的儲存位置

在記憶體中每個類的方法都儲存在類對象中

每個方法都有一個與之對應的SEL類型的資料

根據一個SEL資料就可以找到對應的方法地址,進而調用方法

SEL類型的定義:  typedef struct objc_selector *SEL

 

b.SEL對象的建立

 SEL s1 = @selector(test1);   // 將test1方法封裝成SEL對象 

 SEL s2 = NSSelectorFromString(@"test1");   // 將一個字串方法轉換成為SEL對象

 

c.SEL對象的其他用法

// 將SEL對象轉換為NSString對象  

NSString *str = NSStringFromSelector(@selector(test));

 

執行個體:

Person *p = [Person new];// 調用對象p的test方法[p performSelector:@selector(test)];[person performSelector:@selector(test2:) withObject:@"傳入參數"];
Person類代碼:#import "Person.h"@implementation Person- (void)test{    NSLog(@"無參數的對象方法");}- (void)test2:(NSString *)str{    NSLog(@"帶有參數的方法%@",str);}@end

d:在數組中的運用

// 對一個數組array的每個元素執行一次test方法[array makeObjectsPerformSelector:@selector(test)];[array makeObjectsPerformSelector:@selector(test)  withObject:@"aaa"];//對一個數組array進行排序[array sortedArrayUsingSelector:@selector(compare:)];

e:關於Sel傳參運用(target - action設計模式)

在Button中我們經常用下面進行事件增加代碼:

- (void)addTarget:(nullable id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents;

執行個體:

#import <UIKit/UIKit.h>@interface TapView : UIView//目標@property(weak,nonatomic)id target;//行為@property(assign,nonatomic)SEL action;//自訂方法-(void)addCustomtarget:(id)target andAction:(SEL)action;@end
#import "TapView.h"@implementation TapView//自訂方法-(void)addCustomtarget:(id)target andAction:(SEL)action{    _action = action;    _target = target;}-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{    //當視圖點擊的時候,target去執行action的方法並把自己傳過去.    //首先代理不能是空,而且代理(代理是對象!)的類中有方法並且能傳出過來.    if (nil != _target && [[_target class] instancesRespondToSelector:_action]) {        [_target performSelector:_action withObject:self];    }}

 另一個執行個體:

#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:代理模式執行個體

#import <UIKit/UIKit.h>@protocol TouchViewDelegate <NSObject>-(void)changeViewColor:(UIColor *)color;@end@interface TouchView : UIView//聲明一個代理,這個代理遵守TouchViewDelegate協議,@property(nonatomic,assign)id<TouchViewDelegate> delegate;@end
#import "TouchView.h"@implementation TouchView//我們還是用touchesBegandian-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{    if (nil != self.delegate && [self.delegate respondsToSelector:@selector(changeViewColor:)]) {        //我們傳一個顏色到我們的ViewController去.        [self.delegate changeViewColor:[UIColor brownColor]];    }}@end
運用代碼:#import "ViewController.h"#import "TouchView.h"//在這裡ViewController 要遵守協議....@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];    //指定touchView的代理為ViewController.即為本身~    self.touchView.delegate =self;    [self.view addSubview: self.touchView];}-(void)changeViewColor:(UIColor *)color{    //現在參數color是有值的,這是因為在TouchView那個頁面傳過來的.    self.touchView.backgroundColor = color;}@end

3:關於Bolck運用

#import <UIKit/UIKit.h>//給block改名成MyBlocktypedef void(^MyBlock)(NSString *);@interface OtherViewController : UIViewController//ARC:語義設定使用strong即可@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
運用代碼:    OtherViewController *otherVC = [[OtherViewController alloc]init];    __weak typeof(self)weak = self;    //給block賦值~    otherVC.block = ^(NSString *string){        weak.label.text = string;    };    [self.navigationController pushViewController:otherVC animated:YES];

4:UIButton的幾種觸發方式

a、UIControlEventTouchDown 

  指滑鼠左鍵按下(註:只是“按下”)的動作

b、UIControlEventTouchDownRepeat

  指滑鼠左鍵連續多次重複按下(註:只是“按下”)的動作,比如,滑鼠連續雙擊、三擊、……、多次連擊。

  說明:多次重複按下時,事件序列是這樣的:

  UIControlEventTouchDown -> 

  (UIControlEventTouchUpInside) -> 

  UIControlEventTouchDown -> 

  UIControlEventTouchDownRepeat -> 

  (UIControlEventTouchUpInside) -> 

  UIControlEventTouchDown -> 

  UIControlEventTouchDownRepeat -> 

  (UIControlEventTouchUpInside) ->

  ......

  除了第一次按下外,後面每次摁下都是一個UIControlEventTouchDown事件,然後緊跟一個UIControlEventTouchDownRepeat事件。

cUIControlEventTouchDragInside

  指按下滑鼠,然後在控制項邊界範圍內拖動。

dUIControlEventTouchDragOutside

  與UIControlEventTouchDragInside不同的是,拖動時,滑鼠位於控制項邊界範圍之外。

  但首先得有個UIControlEventTouchDown事件,然後接一個UIControlEventTouchDragInside事件,再接一個UIControlEventTouchDragExit事件,這時,滑鼠已經位於控制項外了,繼續拖動就是UIControlEventTouchDragOutside事件了。

  具體操作是:在控制項裡面按下滑鼠,然後拖動到控制項之外。

eUIControlEventTouchDragEnter

  指拖動動作中,從控制項邊界外到內時產生的事件。

fUIControlEventTouchDragExit

  指拖動動作中,從控制項邊界內到外時產生的事件。

gUIControlEventTouchUpInside

  指滑鼠在控制項範圍內抬起,前提先得按下,即UIControlEventTouchDownUIControlEventTouchDownRepeat事件。

hUIControlEventTouchUpOutside

  指滑鼠在控制項邊界範圍外抬起,前提先得按下,然後拖動到控制項外,即 

  UIControlEventTouchDown -> 

  UIControlEventTouchDragInside(n ) -> 

  UIControlEventTouchDragExit -> 

  UIControlEventTouchDragOutside(n 

  時間序列,再然後就是抬起滑鼠,產生UIControlEventTouchUpOutside事件。

 

5:讓編譯器對一些警告閉嘴

a:方法棄用警示

#pragma clang diagnostic push    #pragma clang diagnostic ignored "-Wdeprecated-declarations"      //會警示告的方法,比如SEL [TestFlight setDeviceIdentifier:[[UIDevice currentDevice] uniqueIdentifier]];    #pragma clang diagnostic pop  

b:未使用變數

#pragma clang diagnostic push   #pragma clang diagnostic ignored "-Wunused-variable"       int a;   #pragma clang diagnostic pop 

 6:一個六邊形,並只在六邊形裡面有點擊效果

#import <UIKit/UIKit.h>//六邊形Button@interface HexagonButton : UIViewNS_ASSUME_NONNULL_BEGINtypedef void (^HexagonButtonBlock)();@property (nonatomic, strong) UIBezierPath *path;@property (nonatomic, strong) CAShapeLayer *maskLayer;@property (nonatomic, strong) HexagonButtonBlock block; //點擊事件//添加點擊事件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;                //添加單擊手勢        UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(click:)];        [self addGestureRecognizer:tap];    }    return self;}- (void) layoutSubviews{    [super layoutSubviews];    CGFloat SIZE = self.frame.size.width;    // step 1: 產生六邊形路徑    CGFloat longSide = SIZE * 0.5 * cosf(M_PI * 30 / 180);    CGFloat shortSide = SIZE * 0.5 * sin(M_PI * 30 / 180);    CGFloat k = SIZE * 0.5 - longSide;  //路徑整體下移,保證六邊形路徑位於圖形中間        _path = [UIBezierPath bezierPath];    [_path moveToPoint:CGPointMake(0, longSide  + k)];    [_path addLineToPoint:CGPointMake(shortSide, + k)];    [_path addLineToPoint:CGPointMake(shortSide + shortSide + shortSide,  k)];    [_path addLineToPoint:CGPointMake(SIZE, longSide + k)];    [_path addLineToPoint:CGPointMake(shortSide * 3, longSide * 2 + k)];    [_path addLineToPoint:CGPointMake(shortSide, longSide * 2 + k)];    [_path closePath];        // step 2: 根據路徑產生蒙板    _maskLayer = [CAShapeLayer layer];    //    _maskLayer.position = self.center;    _maskLayer.path = [_path CGPath];        // step 3: 添加蒙版    self.layer.mask = _maskLayer;    self.backgroundColor = [UIColor orangeColor];}//點擊事件- (void) click:(UITapGestureRecognizer *) tap{    if (_block) {        _block();    }}- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {    //如果點擊的地區在所建立的路徑範圍內    if (CGPathContainsPoint(_path.CGPath, NULL, point, NO)) {        return [super hitTest:point withEvent:event];    }    return nil;}@end
    //建立六變形按鈕    HexagonButton * hexagonButton = [[HexagonButton alloc] initWithFrame:CGRectMake(20, 20, 100, 100)];    hexagonButton.center = self.view.center;    hexagonButton.block = ^(){        NSLog(@"六邊形地區被點擊");    };    [self.view addSubview:hexagonButton];

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.