欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Observing?KVO?Key-Value基本使用原理示例詳解

 更新時(shí)間:2022年08月08日 14:52:55   作者:小橘爺  
這篇文章主要為大家介紹了Observing?KVO?Key-Value基本使用原理示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

正文

Key-Value Observing(KVO) 是一種機(jī)制,它允許對(duì)象在其他對(duì)象的指定屬性發(fā)生更改時(shí)得到通知。要使用 KVO,首先你必須確保被觀察對(duì)象是 KVO 兼容的。通常,如果你的對(duì)象繼承自 NSObject 并且你以通常的方式創(chuàng)建屬性,那么你的對(duì)象及其屬性將自動(dòng)兼容 KVO。

KVO 的主要好處是你不必實(shí)現(xiàn)自己的方案來(lái)在每次屬性更改時(shí)發(fā)送通知,其定義良好的基礎(chǔ)架構(gòu)具有框架級(jí)別的支持。

KVO 的基本使用

你必須執(zhí)行以下步驟以使對(duì)象能夠接收 KVO 兼容屬性的 KVO 通知:

  • 使用方法 addObserver:forKeyPath:options:context: 將觀察者注冊(cè)到被觀察對(duì)象。
  • 在觀察者內(nèi)部實(shí)現(xiàn) observeValueForKeyPath:ofObject:change:context: 以接受更改通知消息。
  • 使用 removeObserver:forKeyPath: 方法取消注冊(cè)觀察者,當(dāng)它不再應(yīng)該接收消息時(shí)。至少,在觀察者從內(nèi)存中釋放之前調(diào)用此方法。

注冊(cè)為觀察者

被觀察對(duì)象首先通過(guò)發(fā)送 addObserver:forKeyPath:options:context: 消息將觀察者注冊(cè)到被觀察對(duì)象,并將觀察者和要觀察的屬性的 keyPath 傳遞。觀察者還指定了一個(gè)選項(xiàng)參數(shù)和一個(gè)上下文指針來(lái)管理通知的各個(gè)方面。

Options

options 參數(shù)為常量選項(xiàng)的按位或,它會(huì)影響通知中提供的 change 字典的內(nèi)容以及生成通知的方式??蛇x的值有如下四個(gè):

typedef NS_OPTIONS(NSUInteger, NSKeyValueObservingOptions) {
    NSKeyValueObservingOptionNew = 0x01, // 新值
    NSKeyValueObservingOptionOld = 0x02, // 舊值
    // 屬性的初始值
    NSKeyValueObservingOptionInitial API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)) = 0x04,
    // 在變化前發(fā)送通知
    // change 字典通過(guò)包含鍵 NSKeyValueChangeNotificationIsPriorKey 和 NSNumber 包裝 YES 的值來(lái)表示更改前通知。
    NSKeyValueObservingOptionPrior API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)) = 0x08
};

Context

addObserver:forKeyPath:options:context: 消息中的 context 指針包含任意數(shù)據(jù),這些數(shù)據(jù)將在相應(yīng)的更改通知中傳遞回觀察者。你可以指定 NULL 并完全依賴 keyPath 字符串來(lái)確定更改通知的來(lái)源,但這種方法可能會(huì)導(dǎo)致父類出于不同原因也觀察相同 keyPath 的對(duì)象出現(xiàn)問(wèn)題。

一種更安全、更可擴(kuò)展的方法是使用上下文來(lái)確保你收到的通知是發(fā)給你的觀察者而不是父類的。

類中唯一命名的靜態(tài)變量的地址是一個(gè)很好的上下文。在父類或子類中以類似方式選擇的上下文不太可能重疊。你可以為整個(gè)類選擇一個(gè)上下文,并依靠通知消息中的 keyPath 字符串來(lái)確定發(fā)生了什么變化?;蛘?,你可以為每個(gè)觀察到的 keyPath 創(chuàng)建一個(gè)不同的上下文,這完全繞過(guò)了字符串比較的需要,從而提高了通知解析的效率。

static void *PersonAccountBalanceContext = &PersonAccountBalanceContext;
static void *PersonAccountInterestRateContext = &PersonAccountInterestRateContext;
- (void)registerAsObserverForAccount:(Account*)account {
    [account addObserver:self
              forKeyPath:@"balance"
                 options:(NSKeyValueObservingOptionNew |
                          NSKeyValueObservingOptionOld)
                 context:PersonAccountBalanceContext];
    [account addObserver:self
              forKeyPath:@"interestRate"
                 options:(NSKeyValueObservingOptionNew |
                          NSKeyValueObservingOptionOld)
                  context:PersonAccountInterestRateContext];
}

需要注意的是 addObserver:forKeyPath:options:context: 方法不維護(hù)對(duì)觀察對(duì)象、被觀察對(duì)象或 context 的強(qiáng)引用。你應(yīng)該確保根據(jù)需要維護(hù)對(duì)觀察對(duì)象和觀察對(duì)象以及 context 的強(qiáng)引用。

接收變更通知

當(dāng)對(duì)象的被觀察屬性的值發(fā)生變化時(shí),觀察者會(huì)收到一個(gè) observeValueForKeyPath:ofObject:change:context: 消息。所有的觀察者都必須實(shí)現(xiàn)這個(gè)方法。

被觀察對(duì)象提供觸發(fā)通知的 keyPath、被觀察對(duì)象、包含有關(guān)更改的詳細(xì)信息的字典以及在為該 keyPath 注冊(cè)觀察者時(shí)提供的上下文指針。

change 字典的 NSKeyValueChangeKindKey 提供有關(guān)發(fā)生的更改類型的信息:

  • 如果被觀察對(duì)象的值發(fā)生了變化,則 NSKeyValueChangeKindKey 對(duì)應(yīng)的值為 NSKeyValueChangeSetting。根據(jù)觀察者注冊(cè)時(shí)指定的選項(xiàng),change 字典中的 NSKeyValueChangeOldKeyNSKeyValueChangeNewKey 條目包含更改之前和之后的屬性值。如果屬性是對(duì)象,則直接提供值。如果屬性是基本數(shù)據(jù)類型或 C 結(jié)構(gòu),則將值包裝在 NSValue 對(duì)象中。
  • 如果觀察到的屬性是一對(duì)多關(guān)系,則 NSKeyValueChangeKindKey 條目還通過(guò)分別返回 NSKeyValueChangeInsertionNSKeyValueChangeRemovalNSKeyValueChangeReplacement 指示關(guān)系中的對(duì)象是否被插入、刪除或替換。
  • change 字典的 NSKeyValueChangeIndexesKey 條目是一個(gè) NSIndexSet 對(duì)象,用于指定更改的關(guān)系中的索引。如果在注冊(cè)觀察者時(shí)將 NSKeyValueObservingOptionNewNSKeyValueObservingOptionOld 指定為選項(xiàng),則 change 字典中的 NSKeyValueChangeOldKeyNSKeyValueChangeNewKey 條目是包含更改前后相關(guān)對(duì)象值的數(shù)組。
- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context {
    if (context == PersonAccountBalanceContext) {
        // Do something with the balance…
    } else if (context == PersonAccountInterestRateContext) {
        // Do something with the interest rate…
    } else {
        // Any unrecognized context must belong to super
        [super observeValueForKeyPath:keyPath
                             ofObject:object
                               change:change
                               context:context];
    }
}

如果你在注冊(cè)觀察者時(shí)指定了 NULL 上下文,則將通知的 keyPath 與你正在觀察的 keyPath 進(jìn)行比較以確定發(fā)生了什么變化。如果你對(duì)所有觀察到的 keyPath 使用單個(gè)上下文,則首先根據(jù)通知的 context 對(duì)其進(jìn)行測(cè)試,并找到匹配項(xiàng),然后使用 keyPath 字符串比較來(lái)確定具體發(fā)生了什么變化。如果你為每個(gè) keyPath 提供了唯一的 context,如上述代碼所示,一系列簡(jiǎn)單的指針比較會(huì)同時(shí)告訴你通知是否針對(duì)此觀察者,如果是,則哪些 keyPath 已更改。

在任何情況下,觀察者應(yīng)該總是調(diào)用父類的 observeValueForKeyPath:ofObject:change:context: 實(shí)現(xiàn),當(dāng)它不能識(shí)別 context(或者在簡(jiǎn)單的情況下,任何 keyPath),因?yàn)檫@意味著一個(gè)父類已經(jīng)注冊(cè)了相關(guān)通知。

移除觀察者

你可以通過(guò)向被觀察對(duì)象發(fā)送 removeObserver:forKeyPath:context: 消息來(lái)移除觀察者,并指定觀察者、keyPathcontext。

- (void)unregisterAsObserverForAccount:(Account*)account {
    [account removeObserver:self
                 forKeyPath:@"balance"
                    context:PersonAccountBalanceContext];
    [account removeObserver:self
                 forKeyPath:@"interestRate"
                    context:PersonAccountInterestRateContext];
}

移除觀察者時(shí),請(qǐng)記住以下幾點(diǎn):

  • 如果尚未注冊(cè)為觀察者,則要求將其作為觀察者移除會(huì)導(dǎo)致 NSRangeException。你可以只調(diào)用一次 removeObserver:forKeyPath:context: 來(lái)對(duì)應(yīng)調(diào)用 addObserver:forKeyPath:options:context:,或者如果這在你的應(yīng)用程序中不可行,請(qǐng)將 removeObserver:forKeyPath:context: 調(diào)用放在 try/catch 塊中處理潛在的異常。
  • 觀察者在釋放時(shí)不會(huì)自動(dòng)移除自己。被觀察對(duì)象繼續(xù)發(fā)送通知,而忽略了觀察者的狀態(tài)。但是,與任何其他消息一樣,發(fā)送到已釋放對(duì)象的更改通知會(huì)觸發(fā)內(nèi)存訪問(wèn)異常。因此,你要確保觀察者在從內(nèi)存中消失之前將自己移除。
  • 該協(xié)議無(wú)法詢問(wèn)對(duì)象是觀察者還是被觀察者。構(gòu)建你的代碼以避免發(fā)生相關(guān)的錯(cuò)誤。一個(gè)典型的模式是在觀察者初始化期間注冊(cè)為觀察者(例如在 initviewDidLoad 中)并在釋放期間取消注冊(cè)(通常在 dealloc 中),確保正確配對(duì)和有序的添加和刪除消息,并且觀察者在它被內(nèi)存釋放之前取消注冊(cè)觀察。

KVO 的觸發(fā)方式

KVO 觸發(fā)的方式有兩種:

  • 自動(dòng)觸發(fā):NSObject 提供了自動(dòng)觸發(fā) KVO 的基本實(shí)現(xiàn)。
  • 手動(dòng)觸發(fā):由開發(fā)者自行控制哪些屬性會(huì)觸發(fā) KVO

自動(dòng)觸發(fā)

// 使用訪問(wèn)器方法
[account setName:@"Savings"];
// 使用 setValue:forKey:.
[account setValue:@"Savings" forKey:@"name"];
// 使用 setValue:forKeyPath:
[document setValue:@"Savings" forKeyPath:@"account.name"];
// 使用 mutableArrayValueForKey: 檢索關(guān)系代理對(duì)象。
Transaction *newTransaction = <#Create a new transaction for the account#>;
NSMutableArray *transactions = [account mutableArrayValueForKey:@"transactions"];
[transactions addObject:newTransaction];

手動(dòng)觸發(fā)

在某些情況下,你可能希望控制通知過(guò)程,例如,盡量減少因應(yīng)用程序特定原因而不必要的觸發(fā)通知,或?qū)⒍鄠€(gè)更改組合到單個(gè)通知中。手動(dòng)觸發(fā)通知提供了執(zhí)行此操作的方法。

手動(dòng)和自動(dòng)通知并不相互排斥。除了已經(jīng)存在的自動(dòng)通知之外,你還可以自由發(fā)布手動(dòng)通知。更典型的是,你可能希望完全控制特定屬性的通知。

在這種情況下,你覆蓋了 automaticNotifiesObserversForKey:NSObject 實(shí)現(xiàn)。對(duì)于要排除其自動(dòng)通知的屬性,automaticNotifiesObserversForKey: 的子類實(shí)現(xiàn)應(yīng)該返回 NO。子類實(shí)現(xiàn)應(yīng)該為任何無(wú)法識(shí)別的鍵調(diào)用 super。

+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)theKey {
    BOOL automatic = NO;
    if ([theKey isEqualToString:@"balance"]) {
        automatic = NO;
    }
    else {
        automatic = [super automaticallyNotifiesObserversForKey:theKey];
    }
    return automatic;
}

要實(shí)現(xiàn)手動(dòng)觸發(fā)觀察者通知,你在更改值之前調(diào)用 willChangeValueForKey:,并在更改值之后調(diào)用 didChangeValueForKey:。

- (void)setBalance:(double)theBalance {
    [self willChangeValueForKey:@"balance"];
    _balance = theBalance;
    [self didChangeValueForKey:@"balance"];
}

如果單個(gè)操作導(dǎo)致多個(gè)鍵更改,則必須嵌套更改通知:

- (void)setBalance:(double)theBalance {
    [self willChangeValueForKey:@"balance"];
    [self willChangeValueForKey:@"itemChanged"];
    _balance = theBalance;
    _itemChanged = _itemChanged+1;
    [self didChangeValueForKey:@"itemChanged"];
    [self didChangeValueForKey:@"balance"];
}

在有序一對(duì)多關(guān)系的情況下,你不僅必須指定更改的鍵,還必須指定更改的類型和所涉及對(duì)象的索引。更改的類型是指定 NSKeyValueChangeInsertion、NSKeyValueChangeRemovalNSKeyValueChangeReplacementNSKeyValueChange。受影響對(duì)象的索引作為 NSIndexSet 對(duì)象傳遞。

- (void)removeTransactionsAtIndexes:(NSIndexSet *)indexes {
    [self willChange:NSKeyValueChangeRemoval
        valuesAtIndexes:indexes forKey:@"transactions"];
    // Remove the transaction objects at the specified indexes.
    [self didChange:NSKeyValueChangeRemoval
        valuesAtIndexes:indexes forKey:@"transactions"];
}

注冊(cè)依賴鍵

在很多情況下,一個(gè)屬性的值取決于另一個(gè)對(duì)象中的一個(gè)或多個(gè)其他屬性的值。如果一個(gè)屬性的值發(fā)生變化,那么派生屬性的值也應(yīng)該被標(biāo)記為變化。如何確保為這些依賴屬性發(fā)布 KVO 通知取決于關(guān)系的基數(shù)。

一對(duì)一的關(guān)系

要為一對(duì)一關(guān)系自動(dòng)觸發(fā)通知,你應(yīng)該覆蓋 keyPathsForValuesAffectingValueForKey: 或?qū)崿F(xiàn)一個(gè)合適的方法,該方法遵循它為注冊(cè)相關(guān)鍵定義的模式。

例如,一個(gè)人的全名取決于名字和姓氏。 返回全名的方法可以寫成如下:

- (NSString *)fullName {
    return [NSString stringWithFormat:@"%@ %@",firstName, lastName];
}

當(dāng) firstNamelastName 屬性發(fā)生更改時(shí),必須通知觀察 fullName 屬性的應(yīng)用程序,因?yàn)樗鼈儠?huì)影響屬性的值。

一種解決方案是覆蓋 keyPathsForValuesAffectingValueForKey: 指定一個(gè)人的 fullName 屬性依賴于 lastNamefirstName 屬性。

+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key {
    NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key];
    if ([key isEqualToString:@"fullName"]) {
        NSArray *affectingKeys = @[@"lastName", @"firstName"];
        keyPaths = [keyPaths setByAddingObjectsFromArray:affectingKeys];
    }
    return keyPaths;
}

你的方法覆寫通常應(yīng)該調(diào)用 super 并返回一個(gè)集合,該集合包括該集合中的任何成員(以免干擾父類中此方法的覆蓋)。

你還可以通過(guò)實(shí)現(xiàn)遵循命名約定 keyPathsForValuesAffecting<Key> 的類方法來(lái)實(shí)現(xiàn)相同的結(jié)果,其中 <Key> 是依賴于值的屬性的名稱(首字母大寫)。使用這種模式,上述代碼可以重寫為名為 keyPathsForValuesAffectingFullName 的類方法:

+ (NSSet *)keyPathsForValuesAffectingFullName {
    return [NSSet setWithObjects:@"lastName", @"firstName", nil];
}

當(dāng)你使用 category 將計(jì)算屬性添加到現(xiàn)有類時(shí),你不能覆蓋 keyPathsForValuesAffectingValueForKey: 方法,因?yàn)槟悴粦?yīng)該覆蓋類中的方法。在這種情況下,實(shí)現(xiàn)一個(gè)匹配的 keyPathsForValuesAffecting<Key> 類方法來(lái)利用這個(gè)機(jī)制。

KVO 實(shí)現(xiàn)細(xì)節(jié)

讓我們來(lái)首先實(shí)現(xiàn)一個(gè)簡(jiǎn)單的使用了 KVOdemo:

@interface Person : NSObject
@property (nonatomic, assign) NSUInteger age;
@end
@implementation Person
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.person = [Person new];
    // 添加監(jiān)聽
    [self.person addObserver:self 
                  forKeyPath:@"age" 
                     options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld 
                     context:nil];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    // 改變對(duì)象屬性值
    self.person.age = 18;
}
- (void)dealloc {
    // 移除監(jiān)聽
    [self.person removeObserver:self forKeyPath:@"age"];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    // 被監(jiān)聽的屬性值改變后的回調(diào)
    NSLog(@"%@", change);
}
@end

addObserver:forKeyPath:options:context: 一行打上斷點(diǎn),會(huì)發(fā)現(xiàn)在添加觀察者的前后,person 對(duì)象的 isa 指針的指向發(fā)生了變化。

添加觀察者前:

添加觀察者后:

尤其可知,KVO 是通過(guò) runtime 動(dòng)態(tài)生成 NSKVONotify_Person 類的方式,并將 person 對(duì)象的 isa 指針指向了新類,來(lái)為我們實(shí)現(xiàn) KVO 的,這套技術(shù)稱之為 isa-swizzling。其中,NSKVONotify_Person 類是 Person 類的子類,NSKVONotify_Person 還重寫了 class 方法,用于在我們進(jìn)行內(nèi)省時(shí),得到的是當(dāng)前類的準(zhǔn)確類。

再將斷點(diǎn)打在 observeValueForKeyPath:ofObject:change:context: 方法中,可以看到,在接收到通知的過(guò)程中,調(diào)用了系統(tǒng)實(shí)現(xiàn)的 _NSSetUnsignedLongLongValueAndNotify: 方法:

正是通過(guò)該方法,實(shí)現(xiàn)了更新屬性值+通知觀察者值有變動(dòng)的功能。該方法也是 Foundation 為我們實(shí)現(xiàn)的一系列針對(duì)不同類型用于在 KVO 時(shí)設(shè)值的方法,想了解該方法的底層實(shí)現(xiàn)可以看下面這篇文章:

iOS開發(fā)KVO實(shí)現(xiàn)細(xì)節(jié)解密

以上就是Observing KVO Key-Value基本使用原理示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Observing KVO Key-Value的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • iOS字體大小適配的3種方法示例代碼

    iOS字體大小適配的3種方法示例代碼

    這篇文章主要給大家介紹了關(guān)于iOS字體大小適配的3種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)各位iOS開發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11
  • IOS應(yīng)用內(nèi)跳轉(zhuǎn)系統(tǒng)設(shè)置相關(guān)界面的方法

    IOS應(yīng)用內(nèi)跳轉(zhuǎn)系統(tǒng)設(shè)置相關(guān)界面的方法

    在iOS開發(fā)中,有時(shí)會(huì)有跳轉(zhuǎn)系統(tǒng)設(shè)置界面的需求,例如提示用戶打開藍(lán)牙或者WIFI,提醒用戶打開推送或者位置權(quán)限等,接下來(lái)通過(guò)本文給大家介紹IOS應(yīng)用內(nèi)跳轉(zhuǎn)系統(tǒng)設(shè)置相關(guān)界面的方法,喜歡的朋友參考下
    2016-02-02
  • iOS實(shí)時(shí)錄音和播放功能

    iOS實(shí)時(shí)錄音和播放功能

    這篇文章主要為大家詳細(xì)介紹了iOS實(shí)時(shí)錄音和播放功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • iOS應(yīng)用中UILabel文字顯示效果的常用設(shè)置總結(jié)

    iOS應(yīng)用中UILabel文字顯示效果的常用設(shè)置總結(jié)

    UILabel組件可以用來(lái)設(shè)置文字內(nèi)容的排版與字體效果等,功能非常多,下面就來(lái)為大家整理一下基本的iOS應(yīng)用中UILabel文字顯示效果的常用設(shè)置總結(jié)
    2016-05-05
  • 詳解iOS webview加載時(shí)序和緩存問(wèn)題總結(jié)

    詳解iOS webview加載時(shí)序和緩存問(wèn)題總結(jié)

    本篇文章主要介紹了iOS webview加載時(shí)序和緩存問(wèn)題總結(jié) ,這兩天學(xué)習(xí)了Vue.js 感覺(jué)組件這個(gè)地方知識(shí)點(diǎn)挺多的,而且很重要,所以,今天添加一點(diǎn)小筆記。
    2017-09-09
  • iOS開發(fā)中導(dǎo)航控制器的基本使用教程

    iOS開發(fā)中導(dǎo)航控制器的基本使用教程

    這篇文章主要介紹了iOS開發(fā)中導(dǎo)航控制器的基本使用教程,代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下
    2015-11-11
  • 詳解Obejective-C中將JSON數(shù)據(jù)轉(zhuǎn)為模型的方法

    詳解Obejective-C中將JSON數(shù)據(jù)轉(zhuǎn)為模型的方法

    這篇文章主要介紹了Obejective-C中JSON數(shù)據(jù)轉(zhuǎn)為模型的方法,同時(shí)介紹了使用jastor庫(kù)的方法,需要的朋友可以參考下
    2016-03-03
  • iOS實(shí)現(xiàn)手動(dòng)和自動(dòng)屏幕旋轉(zhuǎn)

    iOS實(shí)現(xiàn)手動(dòng)和自動(dòng)屏幕旋轉(zhuǎn)

    這篇文章主要為大家詳細(xì)介紹了iOS實(shí)現(xiàn)手動(dòng)和自動(dòng)屏幕旋轉(zhuǎn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • iOS實(shí)現(xiàn)輪盤動(dòng)態(tài)效果

    iOS實(shí)現(xiàn)輪盤動(dòng)態(tài)效果

    這篇文章主要為大家詳細(xì)介紹了iOS實(shí)現(xiàn)輪盤動(dòng)態(tài)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • iOS swift實(shí)現(xiàn)轉(zhuǎn)場(chǎng)動(dòng)畫的方法示例

    iOS swift實(shí)現(xiàn)轉(zhuǎn)場(chǎng)動(dòng)畫的方法示例

    在平時(shí)的iOS開發(fā)中,我們進(jìn)行界面跳轉(zhuǎn)時(shí)一般都是采用系統(tǒng)默認(rèn)的轉(zhuǎn)場(chǎng)動(dòng)畫,而下面這篇文章主要給大家介紹了關(guān)于iOS利用swift實(shí)現(xiàn)轉(zhuǎn)場(chǎng)動(dòng)畫的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-07-07

最新評(píng)論