[iphone] Interface Builder로 작성된 nib 파일을 사용하여 UIView를로드하는 방법
조금 정교한 작업을 시도하고 있지만 가능한 일을하려고합니다. 그래서 여기에 모든 전문가에게 도전이 있습니다 (이 포럼은 많은 사람들이 모여 있습니다 :)).
설문지 “구성 요소”를 작성하고 있는데 NavigationContoller
(my QuestionManagerViewController
) 에로드하려고합니다 . “컴포넌트”는 “빈”UIViewController
, 답변이 필요한 질문에 따라 다른보기를로드 할 수 있습니다.
내가하는 방식은 다음과 같습니다.
- Question1View 객체를
UIView
서브 클래스 로 생성하여IBOutlets
. - (인터페이스 빌더를 사용하여)
Question1View.xib
(내 문제는 어디에 있습니까? )를 작성하십시오.UIViewController
andUIView
클래스를 Question1View 클래스로 설정했습니다 . - 출구를 뷰의 구성 요소와 연결합니다 (IB 사용).
-
나는 우선
initWithNib
내의를QuestionManagerViewController
같이하기 :- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { if (self = [super initWithNibName:@"Question1View" bundle:nibBundleOrNil]) { // Custom initialization } return self; }
코드를 실행할 때 다음 오류가 발생합니다.
2009-05-14 15 : 05 : 37.152 iMobiDines [17148 : 20b] *** 발견되지 않은 예외 ‘
NSInternalInconsistencyException
‘(으) 로 인해 앱을 종료하는 이유 : ‘-[UIViewController _loadViewFromNibNamed:bundle:]
“Question1View”펜촉이로드되었지만 뷰 콘센트가 설정되지 않았습니다.’
viewController 클래스를 만들 필요없이 nib 파일을 사용하여 뷰를로드하는 방법이 있다고 확신합니다.
답변
펜촉을 배열로 처리하는 대신보기에 액세스하는 더 쉬운 방법도 있습니다.
1 ) 나중에 액세스하려는 콘센트가있는 사용자 정의 View 서브 클래스를 작성하십시오. –MyView
2 ) nib를로드하고 처리하려는 UIViewController에서로드 된 nib의 뷰를 보유 할 IBOutlet 특성을 작성하십시오 (예 :
MyViewController (UIViewController 서브 클래스)
@property (nonatomic, retain) IBOutlet UIView *myViewFromNib;
(합성하여 .m 파일로 릴리스하는 것을 잊지 마십시오)
3) IB에서 펜촉을 열고 ( ‘myViewNib.xib’라고 함) 파일 소유자를 MyViewController로 설정하십시오.
4) 이제 파일의 소유자 콘센트 myViewFromNib를 펜촉의 기본보기에 연결하십시오.
5) 이제 MyViewController에서 다음 줄을 작성하십시오.
[[NSBundle mainBundle] loadNibNamed:@"myViewNib" owner:self options:nil];
이제 속성을 “self.myViewFromNib”로 호출하면 펜촉에서 뷰에 액세스 할 수 있습니다!
답변
다들 감사 해요. 나는 내가 원하는 것을 할 수있는 방법을 찾았다.
- 당신
UIView
과 함께 당신 을 만드십시오IBOutlet
. - IB에서 xib를 작성하여 원하는대로 디자인하고 다음과 같이 링크하십시오
UIViewController
. 파일 소유자의보기가 기본보기에 연결되고 해당 클래스가 1) 단계에서 선언됩니다. - 컨트롤을
IBOutlet
s 와 연결하십시오 . -
는
DynamicViewController
부하 / XIB를 볼 것을 결정하는 그 논리를 실행할 수 있습니다. 그것이 결정을 내리면,loadView
방법에 다음과 같이 넣으십시오 :NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:@"QPickOneView" owner:self options:nil]; QPickOneView* myView = [ nibViews objectAtIndex: 1]; myView.question = question;
그게 다야!
메인 번들의 loadNibNamed
메소드는 뷰를 초기화하고 연결을 생성합니다.
이제 ViewController는 메모리의 데이터에 따라 뷰 또는 다른 뷰를 표시 할 수 있으며 “부모”화면은이 논리를 신경 쓸 필요가 없습니다.
답변
답변 중 일부에 대해 잘 모르겠지만 다음에 Google에서 검색 할 때이 답변을 입력해야합니다. 키워드 : “nib에서 UIView를로드하는 방법”또는 “NSBundle에서 UIView를로드하는 방법”
다음은 Apress Beginning iPhone 3 책 (247 페이지의 “새 테이블 뷰 셀 사용”) 에서 거의 100 % 완성 된 코드입니다 .
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *bundle = [[NSBundle mainBundle] loadNibNamed:@"Blah"
owner:self options:nil];
Blah *blah;
for (id object in bundle) {
if ([object isKindOfClass:[Blah class]]) {
blah = (Blah *)object;
break;
}
}
assert(blah != nil && "blah can't be nil");
[self.view addSubview: blah];
}
이것은 클래스가로 설정된 것을 포함하는 nib라는 UIView
서브 클래스 가 있다고 가정합니다 .Blah
Blah
UIView
Blah
카테고리 : NSObject + LoadFromNib
#import "NSObject+LoadFromNib.h"
@implementation NSObject (LoadFromNib)
+ (id)loadFromNib:(NSString *)name classToLoad:(Class)classToLoad {
NSArray *bundle = [[NSBundle mainBundle] loadNibNamed:name owner:self options:nil];
for (id object in bundle) {
if ([object isKindOfClass:classToLoad]) {
return object;
}
}
return nil;
}
@end
스위프트 확장
extension UIView {
class func loadFromNib<T>(withName nibName: String) -> T? {
let nib = UINib.init(nibName: nibName, bundle: nil)
let nibObjects = nib.instantiate(withOwner: nil, options: nil)
for object in nibObjects {
if let result = object as? T {
return result
}
}
return nil
}
}
그리고 사용중인 예 :
class SomeView: UIView {
class func loadFromNib() -> SomeView? {
return self.loadFromNib(withName: "SomeView")
}
}
답변
하나 이상의 Outlet Collection 인 사용자 정의보기 인스턴스를 관리 해야하는 모든 사람들을 위해 다음 과 같이 @Gonso, @AVeryDev 및 @Olie 답변을 병합하고 사용자 정의했습니다.
-
사용자 정의를 작성 하고 원하는 XIB 에서 루트의
MyView : UIView
” 사용자 정의 클래스 ” 로 설정하십시오 .
UIView
-
필요한 모든 아울렛 을 작성하십시오
MyView
(지금 지점 3 이후 IB가UIViewController
원하는대로 아울렛을 사용자 정의보기가 아닌 아울렛에 연결하도록 제안하기 때문에 지금 수행하십시오 ).
-
사용자 정의보기 XIB 의
UIViewController
” 파일 소유자 ” 로 설정하십시오 .
-
에서
UIViewController
새로운 추가UIViews
의 각 인스턴스에 대해MyView
당신이 원하는, 그리고에 연결UIViewController
만드는 아울렛 컬렉션 : 이러한 뷰는 사용자 정의보기 인스턴스에 대해 “래퍼”뷰 역할을합니다;
-
마지막에
viewDidLoad
당신의UIViewController
추가 다음 줄 :
NSArray *bundleObjects; MyView *currView; NSMutableArray *myViews = [NSMutableArray arrayWithCapacity:myWrapperViews.count]; for (UIView *currWrapperView in myWrapperViews) { bundleObjects = [[NSBundle mainBundle] loadNibNamed:@"MyView" owner:self options:nil]; for (id object in bundleObjects) { if ([object isKindOfClass:[MyView class]]){ currView = (MyView *)object; break; } } [currView.myLabel setText:@"myText"]; [currView.myButton setTitle:@"myTitle" forState:UIControlStateNormal]; //... [currWrapperView addSubview:currView]; [myViews addObject:currView]; } //self.myViews = myViews; if need to access them later..
답변
재사용 할 사용자 정의 UIView를 인스턴스화하기 위해 UINib를 사용합니다.
UINib *customNib = [UINib nibWithNibName:@"MyCustomView" bundle:nil];
MyCustomViewClass *customView = [[customNib instantiateWithOwner:self options:nil] objectAtIndex:0];
[self.view addSubview:customView];
이 경우 필요한 파일은 MyCustomView.xib , MyCustomViewClass.h 및 MyCustomViewClass.m
입니다 [UINib instantiateWithOwner]
. 배열 을 반환하는 참고 이므로 재사용하려는 UIView를 반영하는 요소를 사용해야합니다. 이 경우 첫 번째 요소입니다.
답변
UIView
Interface Builder에서 뷰 컨트롤러의 클래스를 하위 클래스로 설정해서는 안됩니다 . 그것은 가장 확실하게 문제의 일부입니다. UIViewController
하위 클래스 또는 사용자 정의 클래스 로 남겨 두십시오 .
XIB에서 유일한보기를로드에 관해서는, 나는 당신이 있다는 가정하에 있었다 있었다 (이 확장되지 않는 경우에도 뷰 컨트롤러의 일종 가지고 UIViewController
인터페이스에서 파일의 소유자로 설정을 사용자의 요구에 너무 무겁 수 있습니다) 인터페이스를 정의하기 위해 사용하려는 경우 빌더. 나는 이것을 확인하기 위해 약간의 연구를했다. 그렇지 않으면의 인터페이스 요소에 액세스 할 UIView
수있는 방법이 없거나 이벤트에 의해 코드의 고유 한 메소드를 트리거 할 수있는 방법이 없기 때문입니다.
UIViewController
뷰의 파일 소유자로 a를 사용하면 뷰 initWithNibName:bundle:
를로드하고 뷰 컨트롤러 객체를 다시 가져올 수 있습니다. IB view
에서 xib의 인터페이스가있는 콘센트를보기로 설정하십시오. 파일 소유자로 다른 유형의 객체를 사용하는 경우 NSBundle
의 loadNibNamed:owner:options:
메소드를 사용하여 펜촉을로드하고 파일 소유자의 인스턴스를 메소드에 전달해야합니다. IB에서 정의한 콘센트에 따라 모든 속성이 올바르게 설정됩니다.
답변
loadNibNamed 대신 UIViewController의 initWithNibName을 사용할 수도 있습니다. 더 간단합니다.
UIViewController *aViewController = [[UIViewController alloc] initWithNibName:@"MySubView" bundle:nil];
[self.subview addSubview:aViewController.view];
[aViewController release]; // release the VC
이제 MySubView.xib 및 MySubView.h / m을 작성하면됩니다. MySubView.xib에서 File ‘s Owner 클래스를 UIViewController로 설정하고 클래스를 MySubView로 설정하십시오.
subview
부모 xib 파일을 사용하여 크기와 위치를 지정할 수 있습니다 .