2013-03-19 56 views
2

我已經在這裏看到了幾個答案,似乎得到了我後,但我不能讓他們任何工作。如何將UIView XIB「導入」UIViewController XIB?

MyView是UIView子類使用圖像和佈局,並在MyView.xib的風格,並在MyView.(h|m)勢必IBOutlets文本字段屈指可數。 File's Owner未在XIB中設置,但MyView是頂級對象的類。在運行時,我通過NSBundle'sloadNibNamed動態加載各種MyView到某些視圖控制器。一切都順其自然。

但我有另一個視圖控制器,MyVC,在設計時我想用MyView的幾個實例來填充。根據直覺,我在MyVC.xib中放置了一個UIView對象,其大小與MyView相同,將其類型設置爲MyView,在MyVC.h中添加了IBOutlet聲明,並連接了該連接。

當我運行時,MyVC顯示沒有MyView。但是,調試表明已建立連接,視圖確實是MyView,並且MyView'sawakeFromNib確實執行。我確信MyVC'sMyView位於層次結構的頂部,因爲我將它的背景設置爲鮮豔的紅色。那麼魔鬼在哪裏MyView

+1

的意見是'awakeFromNib''d,但將有稱爲其'-initWithCoder' init方法,從視圖控制器XIB而非MyView.xib的數據。如果這是有道理的... – 2013-03-19 20:14:08

回答

1

最簡單的解決方案是,更換舊視圖使MyView有一個子視圖,它是其後代視圖的其餘部分的容器。這使您可以在MyVC.xibMyView.xib中的內容之間建立單點聯繫,並可讓您在兩個xib中連接插座。

MyVC.xib中,將每個佔位符視圖的類別設置爲MyView

MyView.xib中,將頂級視圖的類別設置爲UIView。將文件所有者的類別設置爲MyView。如果您在MyView.xib中連接的MyView上有任何網點,您將需要將它們重新連接到文件所有者,因爲頂級視圖不再具有這些網點。

-[MyView initWithCoder:],負載MyView.xib並添加其頂層視圖作爲子視圖。未經測試的例子:

+ (UINib *)nib { 
    static dispatch_once_t once; 
    static UINib *nib; 
    dispatch_once(&once, ^{ 
     nib = [UINib nibWithNibName:NSStringFromClass(self) bundle:[NSBundle bundleForClass:self]]; 
    }); 
    return nib; 
} 

- (id)initWithCoder:(NSCoder *)aDecoder { 
    if (self = [super initWithCoder:aDecoder]) { 
     NSArray *contents = [[self.class nib] instantiateWithOwner:self options:nil][0]; 
     UIView *containerView = contents[0]; 

     // Make sure the container view's size tracks my size. 
     containerView.frame = self.bounds; 
     containerView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; 
     self.autoresizesSubviews = YES; 
     if ([self respondsToSelector:@selector(setTranslatesAutoresizingMaskIntoConstraints:)]) { 
      self.translatesAutoresizingMaskIntoConstraints = YES; 
      containerView.translatesAutoresizingMaskIntoConstraints = YES; 
     } 
     // If you're using autolayout in both xibs, you should probably create 
     // constraints between self and containerView here. 

     [self addSubview:containerView]; 
    } 
    return self; 
} 

這樣做,你可以連接的MyView網點東西MyVC.xib和東西MyView.xib的效果,並且可以在MyVC.xibMyView.xib連接其他對象的網點的MyView實例。但是,您無法將MyVC.xib中的其他對象的插座連接到MyView.xib中的其他對象,反之亦然。

+0

我不確定我對此做過什麼,但你的答案看起來不錯。 – QED 2016-06-01 15:06:56

0

ORIGINAL:覆蓋的initWithCoder,一個糟糕的主意,因爲下面的評論說

新建議:

  • 使用你的技術現在創建MyVC視圖(MyView的情況下,將基本上是空的觀點)

然後在MyVC的viewDidLoad:方法:

  • 創建使用你的筆尖,每一個的那些在MyView的

  • 替換每個空的(即佔位符)MyViews與您剛剛創建的那些,確保幀被適當地設置新的MyView的情況下(設置任何屬性/實例變量,並且使用「 - (無效)exchangeSubviewAtIndex:(NSInteger的)索引1 withSubviewAtIndex:(NSInteger的)索引2」與子視圖陣列中的新的)

+0

這並不是簡單的工作。當你加載筆尖時,它也會*使用'initWithCoder:'。您必須採取預防措施以避免無限遞歸。 – 2013-03-20 17:40:41

+0

@robmayoff猜你會發現當你與大自然搞混時會發生什麼?讓我再嘗試一次。 – 2013-03-20 18:48:23