天天看點

Texture - 子類化

子類化

建立子類時最重要的差別是您是編寫ASViewController還是ASDisplayNode。 這聽起來很明顯,但由于其中一些差異很微妙,是以記住這一點至關重要。

ASDisplayNode

雖然子類化節點類似于編寫UIView子類,但仍需遵循一些指導原則,以確定您充分利用架構并使節點按預期運作。

-init

當使用

nodeBlocks

時, 此方法在背景線程被調用. 但是,因為在

-init

完成之前沒有其他方法可以運作,是以在此方法中永遠不要使用?。

要記住的最重要的事情是你的init方法必須能夠在任何隊列上被調用。最值得注意的是,這意味着您永遠不應初始化任何UIKit對象,觸摸節點的視圖或圖層(例如

node.layer.X

node.view.X

)或在其中添加任何手勢識别器。相反,在

-didLoad

中執行這些操作。

-didLoad

這個方法在概念上類似于UIViewController的

-viewDidLoad

方法; 它被調用一次,并且是後備視圖加載完成的點。它保證在主線程上被調用,并且是進行任何UIKit事物的适當位置(例如添加手勢識别器,觸摸視圖/圖層,初始化UIKit對象)。

-layoutSpecThatFits:

此方法定義布局并在背景線程上執行繁重的計算。 此方法是建構布局規範對象的位置,該對象将生成節點的大小,以及所有子節點的大小和位置。 這是您放置大部分布局代碼的地方。

您建立的布局規範對象具有可延展性,直到它在此方法中傳回為止。 在此之後,它将是不可變的。 重要的是要記住不要緩存布局規範以便以後使用,而是在必要時重新建立它們。

因為它是在背景線程上運作,是以不應在此處設定任何

node.view

node.layer

屬性。 此外,除非您知道自己在做什麼,否則請勿在此方法中建立任何節點。 此外,與其他方法覆寫不同,通過調用super來開始此方法不是必需的。

-layout

在這種方法中調用super是

layoutSpec

的結果被應用的地方;在使用此方法調用super之後,将計算布局規範,并且将測量和定位所有子節點。

-layout

在概念上類似于UIViewController的

-viewWillLayoutSubviews

。這是更改隐藏屬性,根據需要設定基于視圖的屬性(不是可布局屬性)或設定背景顔色的好地方。您可以将背景顔色設定放在-layoutSpecThatFits:中,但可能存在計時問題。如果你碰巧使用任何UIViews,你可以在這裡設定他們的

frames

。但是,您始終可以使用

-initWithViewBlock

建立節點包裝器:然後在其他位置的背景線程上調整此大小。

此方法在主線程上被調用。然而,如果使用布局規範(

layout Specs

),則不應過多依賴此方法,因為從主線程進行布局更為可取。不到十分之一的子類需要這個。

-layout

的一個很好的用途是針對特定情況,在這種情況下,您希望子節點是您的确切大小。例如。當你想要一個collectionNode占據整個螢幕。布局規範不支援這種情況,并且在此方法中使用單行手動設定架構通常最簡單:

subnode.frame = self.bounds;
           

如果你想在

ASViewController

中獲得相同的效果,你可以在

-viewWillLayoutSubviews

中做同樣的事情,除非你的節點是

initWithNode

中的節點:在這種情況下它會自動執行。

ASViewController

ASViewController

是一個正常的

UIViewController

子類,具有管理節點的特殊功能。 因為它是一個UIViewController子類,是以所有方法都是在主線程上被調用(并且你應該總是在主線程上建立一個ASViewController)。

-init

此方法隻會被調用一次, 而且是在 ASViewController 生命周期的非常起始的時間點. 與UIViewController初始化一樣,最佳做法是永遠不要在此方法中通路

self.view

self.node.view

,因為它會強制提前建立視圖。 而是在

-viewDidLoad

中執行任何視圖通路。

ASViewController的指定初始化程式是

initWithNode:

。 典型的初始化程式看起來類似于下面的代碼。 請注意在調用super之前如何建立ASViewController的節點。 ASViewController管理節點的方式與UIViewController管理視圖的方式類似,但初始化略有不同。

- (instancetype)init
{
  _pagerNode = [[ASPagerNode alloc] init];
  self = [super initWithNode:_pagerNode];
  
  // setup any instance variables or properties here
  if (self) {
    _pagerNode.dataSource = self;
    _pagerNode.delegate = self;
  }
  
  return self;
}
           

-loadView

我們建議您不要使用此方法,因為它與

-viewDidLoad

沒有特别的優勢,并且有一些缺點。 但是,隻要不将

self.view

屬性設定為其他值,就可以安全使用。 對

[super loadView]

的調用會将它設定為node.view。

-viewDidLoad

在ASViewController的生命周期中,此方法在

-loadView

之後立即調用一次。 這是您應該通路節點視圖的最早時間。 這是放置任何應該隻運作一次并需要通路視圖/圖層的設定代碼的好地方,例如添加手勢識别器。

絕不應該在此方法中放置布局代碼,因為幾何體更改時不會再次調用它。 注意,對于UIViewController也是如此; 将布局代碼放在此方法中是不好的做法,即使您目前沒有期望更改幾何體。

-viewWillLayoutSubviews

此方法與節點的-layout方法完全同時調用,并且可以在ASViewController的生命周期中多次調用; 每當ASViewController節點的邊界發生變化(包括旋轉,分屏,鍵盤示範)以及層次結構發生變化(兒童被添加,删除或更改大小)時,都會調用它。

為了保持一緻性,最佳做法是将所有布局代碼放在此方法中。 因為它不經常調用,是以即使不直接依賴于大小的代碼也屬于此處。

-viewWillAppear: / -viewDidDisappear:

這些方法在ASViewController節點出現在螢幕上(最早可見)之前以及從視圖層次結構中删除之後(最早不再可見)調用。 這些方法提供了一個很好的機會來啟動或停止與控制器的顯示或解雇相關的動畫。 這也是記錄使用者操作的好地方。

盡管可以多次調用這些方法并且幾何資訊可用,但不會對所有幾何體更改調用它們,是以不應将其用于核心布局代碼(超出特定動畫所需的設定)。