2011-03-16 36 views
3

我想利用ABPersonViewController的簡單性,同時定製它的外觀略有匹配我的應用程序的外觀和感覺。試圖自定義ABPersonViewController - 無法循環其子視圖

我子類ABPersonViewController,並使用this technique,我遍歷ABPersonViewController的視圖層次,這裏是我的輸出:

 
UIView: 0x5a45d80; frame = (0 0; 320 416); autoresize = W+H; layer = > 
    | ABPersonTableView: 0x6041a00; baseClass = UITableView; frame = (0 0; 320 416); clipsToBounds = YES; autoresize = W+H; layer = ; contentOffset: {0, 0}> 
    | | ABMultiCell: 0x5a50080; baseClass = UITableViewCell; frame = (0 94; 320 45); autoresize = W; tag = 10; layer = > 
    | | | UIGroupTableViewCellBackground: 0x5a678d0; frame = (9 0; 302 45); autoresize = W; layer = > 
    | | | UITableViewCellContentView: 0x5a62670; frame = (10 1; 300 43); layer = > 
    | | | | ABMultiCellContentView_Simple: 0x5a4fef0; frame = (0 0; 300 43); text = '(555) 555-5555'; clipsToBounds = YES; layer = > 
    | | | | | UILabel: 0x5a61590; frame = (5 14.54; 70 16); text = 'mobile'; clipsToBounds = YES; userInteractionEnabled = NO; layer = > 
    | | | | | ABDividerView: 0x5a62ff0; frame = (79 0; 1 44); alpha = 0; layer = > 
    | | | | | | ABSteadfastLineView: 0x5a53ab0; frame = (0 0; 1 44); layer = > 
    | | | | | ABHighlightingTextField: 0x5a53c30; baseClass = UITextField; frame = (85 12; 210 21); text = '(555) 555-5555'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = > 
    | | | | | | UITextFieldLabel: 0x5a53db0; frame = (0 0; 210 19); text = '(530) 305-0835'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = > 
    | | UIView: 0x5a5b300; frame = (0 0; 320 94); layer = > 
    | | | ABPersonTableHeaderView: 0x5a444b0; frame = (0 0; 320 94); clipsToBounds = YES; autoresize = W; layer = > 
    | | | | ABPersonImageView: 0x5a449c0; baseClass = UIControl; frame = (19 15; 64 64); clipsToBounds = YES; autoresize = RM+BM; layer = > 
    | | | | | ABClippingImageView: 0x5a6aae0; frame = (0 0; 64 64); opaque = NO; userInteractionEnabled = NO; layer = > 
    | | | | | ABImageWellLabelView: 0x5a6c0b0; frame = (0 0; 64 64); alpha = 0; opaque = NO; userInteractionEnabled = NO; layer = > 
    | | | | ABPersonNameEditingViewContainer: 0x5a4a9e0; frame = (101 15; 530 64); alpha = 0; autoresize = W+BM; layer = > 
    | | | | | ABMultiCellContentView_Name: 0x5a4b480; frame = (1 0; 208 64); clipsToBounds = YES; layer = > 
    | | | | | | ABHighlightingTextField: 0x5a4d7c0; baseClass = UITextField; frame = (-5 12; 10 21); text = 'First Name'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; tag = 1; layer = > 
    | | | | | | | UITextFieldLabel: 0x5a4b3e0; frame = (-10 0; 10 19); text = 'First Name'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = > 
    | | | | | | ABHighlightingTextField: 0x5a50a90; baseClass = UITextField; frame = (-5 56; 10 21); text = 'Last Name'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; tag = 2; layer = > 
    | | | | | | | UITextFieldLabel: 0x5a4e5d0; frame = (-10 0; 10 19); text = 'Last Name'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = > 
    | | | | | | ABDividerView: 0x5a52300; frame = (0 44; 0 1); layer = > 
    | | | | | | | ABSteadfastLineView: 0x5a525d0; frame = (0 0; 0 1); layer = > 
    | | | | | | ABHighlightingTextField: 0x5a52400; baseClass = UITextField; frame = (-5 100; 10 21); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; tag = 3; layer = > 
    | | | | | | | UITextFieldLabel: 0x5a5a4e0; frame = (-8 0; 10 19); text = 'Company'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = > 
    | | | | | | ABDividerView: 0x5a53f00; frame = (0 88; 0 1); layer = > 
    | | | | | | | ABSteadfastLineView: 0x5a53f80; frame = (0 0; 0 1); layer = > 
    | | | | ABPersonNameDisplayView: 0x5a45cf0; baseClass = UIControl; frame = (97 15; 204 64); autoresize = W; layer = > 
    | | | | | UILabel: 0x5a4bbd0; frame = (0 21; 109 23); text = 'First Name Last Name'; clipsToBounds = YES; autoresize = W; userInteractionEnabled = NO; layer = > 
    | | | | | UILabel: 0x5a4c020; frame = (0 0; 204 0); clipsToBounds = YES; autoresize = W; userInteractionEnabled = NO; layer = > 
    | | UIImageView: 0xcc032a0; frame = (0 409; 320 7); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = > 
    | | UIImageView: 0xcc03350; frame = (313 262; 7 154); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = > 

甜!所以我應該能夠通過UIView的子視圖遞歸循環,並且改變我的內容。

問題是,當執行此循環時,根UIView只顯示一個子視圖 (ABPersonTableView),我不能再深入了。

任何想法爲什麼? ABPersonTableView是隱藏它創建/包含的所有內容的私有類嗎?

我能夠通過這樣做我的遞歸循環中改變表格的背景顏色:

 
if ([subview isKindOfClass:[UITableView class]]) { 
    ((UITableView *)subview).backgroundColor = [UIColor purpleColor]; 
} 

但是,我不能訪問任何UILabels的,因爲我不能得到任何的ABPersonTableView的子視圖。

任何想法?

回答

4

你被卡住,因爲蘋果只提供了兩種方式:

  1. 蘋果內置的,自動的,超級簡單的外觀和感覺的方式(即非cutomizeable)
  2. 滾你自己,你做所有使用地址簿的低級調用

ABPersonViewController及其子視圖不打算修改,這樣做並不保證可用於將來的軟件更新。

原因是蘋果想要一致的外觀和感覺。

如果您確實需要與您的應用程序外觀相匹配,則必須使用上述方法2)並從頭開始重新實施整個過程。這不一定困難,但肯定耗時。

編輯:看到最終解決的海報Q值

+0

感謝amattn。我完全理解我擁有的兩種選擇。然而,我想知道爲什麼我不能在運行我的代碼時進一步進入視圖層次結構。調試器使用recursiveDescription抓取所有子視圖沒有問題。所以我的問題是,蘋果有意阻止訪問子視圖ABPersonTableView? – djibouti33 2011-03-16 18:02:00

+1

可能是。或者可能是因爲大部分內容都會在稍後才加載。嘗試做viewDidAppear或第二個左右後,細胞可見... – amattn 2011-03-16 18:03:47

+0

這是它!如果我在viewDidAppear中循環,我可以訪問所有的子視圖。比我在我腦中形成的原因簡單得多! :)不幸的是,由於它處於viewDidAppear狀態,因此默認狀態會加載,然後您可以看到所有更改。不是一個好的體驗。嘗試在-viewWillAppear,但子視圖尚未準備好。在計劃B! – djibouti33 2011-03-16 18:12:03

0

評論你在-viewDidLoad這樣做呢?您可能必須等到表視圖完成調用後才能將其作爲數據源在內部使用,以創建其所有單元格。您可以通過在表上調用-reloadData或等待一個週期(使用-performSelector:withObject:afterDelay:延遲0),然後然後嘗試混淆其單元格內容。

+0

絕對。在-viewDidLoad中做所有事情。 – djibouti33 2011-03-16 17:56:09

1

請注意,Apple明確警告不要修改標準用戶界面元素的外觀和/或操作標準視圖和控件的子視圖。如果你只是爲自己而構建,沒有問題,但如果你打算將這個應用程序提交給應用程序商店,則準備拒絕。

所有這一切,這是一個很好的問題。

+0

瞭解@Caleb,感謝您的深思熟慮。這將用於應用商店,而我目前的計劃是簡單地使用我自己的VC和tableView重建ABPersonViewController,通過地址簿API直接獲取聯繫人數據。雖然我知道你沒有權利說出蘋果會或不會做什麼,但是你看到過蘋果的任何警告或實際的應用程序被拒絕的情況,因爲他們採用了我建議的路線嗎? – djibouti33 2011-03-17 05:12:27

+0

如果你的選擇器看起來像你的選擇器而不是蘋果的,我懷疑你會遇到麻煩。如果你的可能被誤認爲是他們的,那可能會導致問題。除此之外,我認爲蘋果公司會努力爲標準(或標準外觀)界面元素提供一致的行爲,而且我不會惹惱這些。 – Caleb 2011-03-17 05:58:53

1

您可以調用layoutSubViews後viewDidLoad中訪問ABPersonTableView :) 例如:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // get ABPersonTableView and forced it layout subviews 
    UIView *personTableView = [self.view.subviews objectAtIndex:0]; 
    [personTableView layoutSubviews]; 

    // loop through subviews and customize all exceps contacts image 
    NSArray *subViews = personTableView.subviews; 
    UIView *view; 
    for(int i = 0; i < subViews.count-1; i++) { 
    view = [subViews objectAtIndex:i]; 
    //...customize cells 
    }  
}