programing

Interface Builder로 작성된 nib 파일을 사용하여 UIView를 로드하는 방법

topblog 2023. 4. 13. 20:28
반응형

Interface Builder로 작성된 nib 파일을 사용하여 UIView를 로드하는 방법

좀 정교한 일을 하려고 하는데 가능해야 할 일을 하고 있어요.여기 모든 전문가에게 과제가 있습니다(이 포럼은 많은 전문가들로 구성되어 있습니다).

컴포넌트, '컴포넌트'를 '컴포넌트'에 .NavigationContoller(내)QuestionManagerViewControllerUIViewController응답할 필요가 있는 질문에 따라 다른 뷰를 로드할 수 있습니다.

내가 하는 방법은:

  1. 를 Question1View로 .UIView, 일부의 「」, 「」, 「」IBOutlets.
  2. Builder를 하여 (Interface Builder를 사용하여)를 만듭니다.Question1View.xib (여기서 문제가 발생할 가능성이 있습니다).둘 다 설정했습니다.UIViewControllerUIViewQUESTION1View를 선택합니다.
  3. 콘센트를 뷰의 컴포넌트와 링크합니다(IB 사용).
  4. 이이 the the the the the the the the .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'는 'Question1View'입니다.

viewController 클래스를 만들지 않고 nib 파일을 사용하여 보기를 로드할 수 있는 방법이 있을 것입니다.

또한 니브를 배열로 처리하는 대신 뷰에 쉽게 액세스할 수 있는 방법도 있습니다.

1) 나중에 액세스 할 수 있는 콘센트가 있는 커스텀 View 서브클래스를 만듭니다.--MyView

2) Nib를 로드하고 처리하려는 UIViewController에서 로드된 Nib의 보기를 유지하는 IBOutlet 속성을 만듭니다.

[MyViewController](UIViewController 서브클래스)의

  @property (nonatomic, retain) IBOutlet UIView *myViewFromNib;

(통합하는 것을 잊어버리고 .m파일에 공개합니다.)

3) IB에서 니브를 열고('myViewNib.xib'라고 부릅니다), 파일의 Owner를 MyViewController설정합니다.

4) 이제 파일의 소유자 아웃렛 myViewFromNib를 니브의 메인 뷰에 연결합니다.

5) MyViewController에서 다음 행을 입력합니다.

[[NSBundle mainBundle] loadNibNamed:@"myViewNib" owner:self options:nil];

이 작업을 수행하는 즉시 속성을 "self.myViewFromNib"라고 부르면 니브에서 뷰에 액세스할 수 있습니다.

모두에게 감사를 표합니다.난 내가 원하는 걸 할 수 있는 방법을 찾았어.

  1. 의 create하다다를 작성하다UIViewIBOutlet필요한 경우
  2. IB에서 xib를 만들고 원하는 대로 설계한 후 다음과 같이 링크합니다. 일일 the the the the 。UIViewController(커스텀 서브클래스는 없지만 "진짜" 서브클래스는 없습니다).파일 소유자 보기가 기본 보기에 연결되고 해당 클래스가 1단계부터의 보기로 선언됩니다.
  3. 을 「」로 합니다.IBOutlets.
  4. DynamicViewController는 로직을 실행하여 로드할 뷰/xib를 결정할 수 있습니다.일단 성공하고 나면,loadView요: 아, 맞다, 는는, 습니, 습 method, 같 method, put method, put method.

    NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:@"QPickOneView"
                                                      owner:self
                                                    options:nil];
    
    QPickOneView* myView = [ nibViews objectAtIndex: 1];
    
    myView.question = question;
    

바로 그거야!

번들의 인인 the the the the theloadNibNamed메소드는 보기를 초기화하고 연결을 만듭니다.

이제 View Controller는 메모리 내의 데이터에 따라 보기 또는 다른 보기를 표시할 수 있으며, "부모" 화면은 이 논리를 신경 쓸 필요가 없습니다.

몇 가지 답변이 무엇인지 잘 모르겠지만, 다음에 구글에서 검색할 때 이 답변을 여기에 올려놓아야 합니다.키워드: "Nib에서 UIView 로드 방법" 또는 "NSBundle에서 UIView 로드 방법"

다음은 iPhone 3의 Apress Begining 책에서 거의 100%에 가까운 코드입니다(페이지 247 "Using The New Table View Cell").

- (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];
} 

은 여러분이 '아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아'UIViewsub called called called라는 Blah、 called called 、 called called , , , , 。Blah 명령어에는 「」가 되어 있습니다.UIView가 그 which which which which which which which which which which which which which which 、 which 、 which 、 which 、 which 、 which which 。Blah.


카테고리: NSObject+Load From Nib

#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")
    }
}

커스텀 뷰의 여러 인스턴스를 관리해야 하는 모든 사용자(아울렛 컬렉션)에 대해 다음과 같은 방법으로 @Gonso, @AVeryDev 및 @Olie 응답을 통합하고 커스터마이즈했습니다.

  1. 「」을 합니다.MyView : UIView루트의 "커스텀 클래스"로 설정합니다.UIView원하는 XIB에서커스텀 클래스

  2. 필요한 모든 콘센트를 만듭니다.MyView 3 를 (「」3 「IB」)에합니다.UIViewController 「커스텀 뷰」를 선택합니다.커스텀 클래스 아웃렛

  3. ★★의 UIViewController커스텀 XIB의 "파일 소유자"로 지정합니다.여기에 이미지 설명 입력

  4. 서서 UIViewController UIViewsMyView 대로'로.UIViewController아웃렛 컬렉션 작성: 이러한 뷰는 커스텀 뷰인스턴스의 "래퍼" 뷰로 기능합니다.여기에 이미지 설명 입력

  5. ★★★★★★★★★★★★★★★★★★★★에서는,viewDidLoadUIViewController다음 행을 추가합니다.

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..

UINib를 사용하여 재사용할 커스텀 UIView를 인스턴스화합니다.

UINib *customNib = [UINib nibWithNibName:@"MyCustomView" bundle:nil];
MyCustomViewClass *customView = [[customNib instantiateWithOwner:self options:nil] objectAtIndex:0];
[self.view addSubview:customView];

이 경우 필요한 파일은 MyCustomView.xib, MyCustomViewClass.hMyCustomViewClass.m 입니다.주의:[UINib instantiateWithOwner]는 배열을 반환하므로 재사용할 UIView를 반영하는 요소를 사용해야 합니다.이 경우 첫 번째 요소입니다.

는 '부재하다'의 할 수 .UIView[ Interface Builder ]를 선택합니다.그것은 적어도 당신 문제의 일부임은 확실하다.은 「 「 」로 해 .UIViewController

xib에서 뷰만 로드하는 것에 대해서는 뷰 컨트롤러가 있어야 한다고 상정하고 있었습니다(확장이 되지 않는 경우에도).UIViewController(필요에 따라 너무 무거울 수 있음)를 사용하여 인터페이스를 정의하는 경우 [Interface Builder]에서 [File's Owner]으로 설정합니다.저도 이 사실을 확인하기 위해 약간의 조사를 했습니다. 않으면 에 수 입니다.UIView코드의 독자적인 메서드를 이벤트에 의해서 트리거 하는 방법도 없습니다.

「 」를 하는 경우UIViewController as as as 、 음음 、 음음 、 음음음음음음음 as as as as as as as as as as as as 。initWithNibName:bundle:로드하고 뷰 컨트롤러 개체를 다시 가져옵니다.를 설정합니다.viewxib에서 인터페이스를 사용하여 뷰에 연결할 수 있습니다. 소유자를 사용해야 NSBundle의 »loadNibNamed:owner:options:메서드를 사용하여 니브를 로드하고 파일 소유자의 인스턴스를 메서드에 전달합니다.IB에서 정의한 콘센트에 따라 모든 속성이 올바르게 설정됩니다.

loadNibName 대신 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에서 파일의 소유자 클래스를 UIViewController로 설정하고 뷰 클래스를 MySubView로 설정합니다.

of of of of you 、 you 、 of 、 of 、 of 、 of 、 of 、 of 、 。subview부모 xib 파일을 사용합니다.

이것은 훌륭한 질문(+1)입니다.답변은 거의 도움이 되었습니다.죄송합니다만, Gonso와 AVeryDev가 모두 좋은 힌트를 주었습니다만, 저는 이것에 대해 고생했습니다.바라건대, 이 대답이 다른 사람들에게 도움이 될 것이다.

MyVC뷰 컨트롤러가 이 모든 것을 보관하고 있습니다.

MySubview는 xibxib에서입니다.

  • 에서 MyVC.xib 유형의 .MySubView적절한 크기, 모양, 원하는 위치에 배치할 수 있습니다.
  • MyVC.h에서

    IBOutlet MySubview *mySubView
    // ...
    @property (nonatomic, retain) MySubview *mySubview;
    
  • 에서는 MyVC.m에서@synthesize mySubView; 꼭 해 주세요.dealloc.

  • 에서 MySubview의 합니다.h에 다음 콘센트/속성을 설정합니다.UIView *view(불필요할 수도 있지만, 나에게는 효과가 있었다.)합니다.
  • MySubview.xib
    • 을 " "로 설정합니다.MySubview뷰 속성을 뷰에 링크합니다.
    • 비트를 하여 " "에 합니다.IBOutlet
  • MyVC.m으로 돌아가서

    NSArray *xibviews = [[NSBundle mainBundle] loadNibNamed: @"MySubview" owner: mySubview options: NULL];
    MySubview *msView = [xibviews objectAtIndex: 0];
    msView.frame = mySubview.frame;
    UIView *oldView = mySubview;
    // Too simple: [self.view insertSubview: msView aboveSubview: mySubview];
    [[mySubview superview] insertSubview: msView aboveSubview: mySubview]; // allows nesting
    self.mySubview = msView;
    [oldCBView removeFromSuperview];
    

나에게 있어서 곤란한 것은, 다른 회답의 힌트가, Xib로부터 나의 견해를 로드했지만, MyVC의 뷰를 대체하지 않았다(duh!)--그것을 스스로 교환할 필요가 있었다.

「 」에 액세스 , 「 」를 참조해 주세요.mySubview 「」의view은 .xib로 .MySubview 않으면,은 평범한 옛날의 것으로 UIView.

하는 mySubview그 자체에서 직접 꺼내면 좋겠지만, 이 덕분에 내가 있어야 할 곳에 도착했어요.

이것은 좀 더 쉬워야 할 것이다.는 결국 연장하게 되었다.는결 i i i i i i i i i i i i i i 。UIViewController " " " 를 추가합니다.loadNib:inPlaceholder:이제 알 수 있다

self.mySubview = (MyView *)[self loadNib:@"MyView" inPlaceholder:mySubview];

이 카테고리의 코드는 다음과 같습니다(Gonso에서 설명한 것과 같은 리가마롤을 수행합니다).

@interface UIViewController (nibSubviews)

- (UIView *)viewFromNib:(NSString *)nibName;
- (UIView *)loadNib:(NSString *)nibName inPlaceholder:(UIView *)placeholder;

@end

@implementation UIViewController (nibSubviews)

- (UIView *)viewFromNib:(NSString *)nibName
{
  NSArray *xib = [[NSBundle mainBundle] loadNibNamed:nibName owner:self options:nil]; 
  for (id view in xib) { // have to iterate; index varies
    if ([view isKindOfClass:[UIView class]]) return view;
  }
  return nil;
}

- (UIView *)loadNib:(NSString *)nibName inPlaceholder:(UIView *)placeholder
{
  UIView *nibView = [self viewFromNib:nibName];
  [nibView setFrame:placeholder.frame];
  [self.view insertSubview:nibView aboveSubview:placeholder];
  [placeholder removeFromSuperview];
  return nibView;
}

@end

재빠르게

실제로 이 문제에 대한 저의 해결방법은 다음과 같이 뷰를 사용하는 CustonViewController의 viewDidLoad에 뷰를 로드하는 것이었습니다.

myAccessoryView = NSBundle.mainBundle().loadNibNamed("MyAccessoryView", owner: self, options: nil)[0] as! MyAccessoryView

loadView()는 커스텀ViewController.loadView View를 로드하기 위한 입니다.

저도 비슷한 작업을 하고 싶었지만, 다음과 같은 사실을 알게 되었습니다. (SDK 3.1.3)

뷰 컨트롤러 A(Nav 컨트롤러 자체 소유)를 가지고 있으며 버튼을 누르면 VC B가 로딩됩니다.

AViewController.m의 경우

BViewController *bController = [[BViewController alloc] initWithNibName:@"Bnib" bundle:nil];
[self.navigationController pushViewController:bController animated:YES];
[bController release];

현재 VC B는 Bnib에서 인터페이스를 가지고 있지만 버튼을 누르면 다른 Nib와 별도의 UI를 가진 '편집 모드'로 가고 싶지만 편집 모드에 새로운 VC를 원하지 않고 새로운 Nib를 기존 B VC와 연관짓고 싶습니다.

따라서 BViewController.m(버튼 누름 방식)에서

NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:@"EditMode" owner:self options:nil];
UIView *theEditView = [nibObjects objectAtIndex:0];
self.editView = theEditView;
[self.view addSubview:theEditView];

그런 다음 다른 버튼에서 (편집 모드를 종료하려면)를 누릅니다.

[editView removeFromSuperview];

원래 Bnib으로 돌아왔습니다

이것은 정상적으로 동작합니다만, 제 EditMode.nib 에는 UIView obj가 1개밖에 없습니다.이 니브의 파일 소유자가 BViewController로 설정되어 있는지 기본 NSObject로 설정되어 있는지 여부는 중요하지 않습니다.단, 파일 소유자의 뷰 아웃렛이 아무것도 설정되어 있지 않은지 확인하십시오.이 경우 exc_bad_access 크래시가 발생하고 xcode는 반복하여 호출된 내부 UIView 메서드를 나타내는 6677 스택프레임 로드를 계속 진행합니다.무한 루프처럼 보입니다.(View Outlet IS는 원래 Bnib로 설정되어 있습니다)

이게 도움이 됐으면 좋겠다.

마음에 드는 카테고리를 만들었습니다.

UIView+NibInitializer.h

#import <UIKit/UIKit.h>

@interface UIView (NibInitializer)
- (instancetype)initWithNibNamed:(NSString *)nibNameOrNil;
@end

UIView+NibInitializer.m

#import "UIView+NibInitializer.h"

@implementation UIView (NibInitializer)

- (instancetype)initWithNibNamed:(NSString *)nibNameOrNil
{
    if (!nibNameOrNil) {
        nibNameOrNil = NSStringFromClass([self class]);
    }
    NSArray *viewsInNib = [[NSBundle mainBundle] loadNibNamed:nibNameOrNil
                                                        owner:self
                                                      options:nil];
    for (id view in viewsInNib) {
        if ([view isKindOfClass:[self class]]) {
            self = view;
            break;
        }
    }
    return self;
}

@end

그 후, 다음과 같이 호출합니다.

MyCustomView *myCustomView = [[MyCustomView alloc] initWithNibNamed:nil];

니브의 이름이 클래스 이름이 아닌 다른 이름으로 지정된 경우 니브 이름을 사용합니다.

추가 동작을 위해 서브클래스로 덮어쓰려면 다음과 같이 됩니다.

- (instancetype)initWithNibNamed:(NSString *)nibNameOrNil
{
    self = [super initWithNibNamed:nibNameOrNil];
    if (self) {
        self.layer.cornerRadius = CGRectGetHeight(self.bounds) / 2.0;
    }
    return self;
}

스위프트:

  1. 「」을 합니다.UIView서브클래스와 xib 파일(자신의 클래스명(MemeView의 경우)을 따서 이름 붙입니다.Meme View 클래스 내에서는 이 클래스를 설계할 수 있는 것으로 정의하는 것을 잊지 마십시오.@IBDesignable
  2. 「Xib」를 의 「File를 말아 주세요.UIViewIndetity Inspector (Indetity Inspector)

    여기에 이미지 설명 입력

  3. xib 파일에서는, 인터페이스 구축, 제약, 아웃렛 작성, 액션등을 실시할 수 있게 되었습니다.여기에 이미지 설명 입력

  4. 초기화가 완료되면 xib를 열려면 커스텀 클래스에 몇 가지 메서드를 구현해야 합니다.

    class XibbedView: UIView {

    weak var nibView: UIView!
    
    override convenience init(frame: CGRect) {
        let nibName = NSStringFromClass(self.dynamicType).componentsSeparatedByString(".").last!
        self.init(nibName: nibName)
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        let nibName = NSStringFromClass(self.dynamicType).componentsSeparatedByString(".").last!
        let nib = loadNib(nibName)
        nib.frame = bounds
        nib.translatesAutoresizingMaskIntoConstraints = false
        addSubview(nib)
        nibView = nib
        setUpConstraints()
    }
    
    init(nibName: String) {
        super.init(frame: CGRectZero)
        let nibName = NSStringFromClass(self.dynamicType).componentsSeparatedByString(".").last!
        let nib = loadNib(nibName)
        nib.frame = bounds
        nib.translatesAutoresizingMaskIntoConstraints = false
        addSubview(nib)
        nibView = nib
        setUpConstraints()
    }
    
    func setUpConstraints() {
        ["V","H"].forEach { (quote) -> () in
            let format = String(format:"\(quote):|[nibView]|")
            addConstraints(NSLayoutConstraint.constraintsWithVisualFormat(format, options: [], metrics: nil, views: ["nibView" : nibView]))
        }
    }
    
    func loadNib(name: String) -> UIView {
        let bundle = NSBundle(forClass: self.dynamicType)
        let nib = UINib(nibName: name, bundle: bundle)
        let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView
    
        return view
    }
    

    }

  5. 에서는, 빌더로부터 하게 제어할 수 , 몇개의 .

    @IBDesignable class MemeView: XibbedView {

    @IBInspectable var memeImage: UIImage = UIImage() {
        didSet {
            imageView.image = memeImage
        }
    }
    @IBInspectable var textColor: UIColor = UIColor.whiteColor() {
        didSet {
            label.textColor = textColor
        }
    }
    @IBInspectable var text: String = "" {
        didSet {
            label.text = text
        }
    }
    @IBInspectable var roundedCorners: Bool = false {
        didSet {
            if roundedCorners {
                layer.cornerRadius = 20.0
                clipsToBounds = true
            }
            else {
                layer.cornerRadius = 0.0
                clipsToBounds = false
            }
        }
    }
    
    @IBOutlet weak var label: UILabel!
    @IBOutlet weak var imageView: UIImageView!
    

}

가지 예: " " " 입니다.
여기에 이미지 설명 입력여기에 이미지 설명 입력

정보를 있는 또는 다른 xib에 되어 있는 를 구현하려면 이 을 수행합니다.prepareForInterfaceBuilder()이 메서드는 인터페이스 빌더에서 파일을 열 때만 실행됩니다.내가 쓴 모든 것을 실행했지만 아무것도 작동하지 않는 경우 구현에 중단점을 추가하여 시그글뷰를 디버깅하는 방법이 있습니다.여기에 이미지 설명 입력
뷰 계층은 다음과 같습니다.계층 구조 보기

여기에서 전체 샘플을 다운로드할 수 있기를 바랍니다.

Aaron Hillegass(저자, 강사, 코코아 닌자)의 블로그 투고는 매우 계몽적이었다.지정된 이니셜라이저를 통해 NIB 파일을 로드하는 그의 수정된 접근 방식을 채택하지 않더라도 최소한 진행 중인 프로세스를 더 잘 이해할 수 있을 것입니다.요즘 이 방법을 써서 성공을 거두고 있어요!

이전 답변에서는 iPhone SDK의 2.0과 2.1 사이에서 발생한 NIB(XIB) 구조의 변경은 고려하지 않았습니다.이제 사용자 컨텐츠는 1이 아닌 인덱스 0에서 시작됩니다.

2.1 매크로를 사용할 수 있습니다.이것은 버전 2.1 이후에 유효합니다(아이폰 앞에 두 개의 밑줄입니다).

 // Cited from previous example
 NSArray* nibViews =  [[NSBundle mainBundle] loadNibNamed:@"QPickOneView" owner:self options:nil];
 int startIndex;
 #ifdef __IPHONE_2_1
 startIndex = 0;
 #else
 startIndex = 1;
 #endif
 QPickOneView* myView = [ nibViews objectAtIndex: startIndex];
 myView.question = question;

대부분의 어플리케이션에서 이와 유사한 기술을 사용하고 있습니다.

바니

) 같은 할 이유가 , 이으로 XIB의 .UIView(예: 「」, 「」, 「」, 「」를 참조해 주세요.이를 위해 다음과 같은 유틸리티 메서드를 만들었습니다.

+ (id) initWithNibName:(NSString *)nibName withSelf:(id)myself {

    NSArray *bundle = [[NSBundle mainBundle] loadNibNamed:nibName
                                                    owner:myself options:nil];
    for (id object in bundle) {
        if ([object isKindOfClass:[myself class]]) {
            return object;
        }
    }  

    return nil;
} 

저는 서브클래스에서 요' 럼럼 ''' ' then 。initWithFrame다음과 같이 합니다.

- (id)initWithFrame:(CGRect)frame {

    self = [Utilities initWithNibName:@"XIB1" withSelf:self];
    if (self) {
        // Initialization code.
    }
    return self;
}

일반인용 게시물입니다.이렇게 하지 않아도 문제가 발견되면 알려주세요.

Swift로 하는 방법은 다음과 같습니다(현재 XCode 7 베타 5에서 Swift 2.0으로 표기).

의 ★★★★★★에서UIViewInterface Builder "Custom Class" "Custom Class" "Custom Class" "Custom Class" "Custom Class" "Custom Class" "Custom Class" (Custom Class) "Cauda")

class func loadFromNib() -> RecordingFooterView? {
    let nib = UINib(nibName: "RecordingFooterView", bundle: nil)
    let nibObjects = nib.instantiateWithOwner(nil, options: nil)
    if nibObjects.count > 0 {
        let topObject = nibObjects[0]
        return topObject as? RecordingFooterView
    }
    return nil
}

그럼 이렇게 부르면 되겠네요.

let recordingFooterView = RecordingFooterView.loadFromNib()

@AVeryDev

6) 로드된 뷰를 뷰 컨트롤러의 뷰에 연결하려면:

[self.view addSubview:myViewFromNib];

메모리 누수를 방지하기 위해 뷰에서 삭제해야 합니다.

명확히 하기 위해 뷰 컨트롤러에는 몇 가지 IBOutlet이 있으며, 그 중 일부는 원래 니브 파일의 항목(통상대로)에 연결되고 일부는 로드된 니브의 항목에 연결됩니다.둘 다 주인 계급이 같아로드된 보기가 원래 보기와 겹칩니다.

힌트: 로드된 니브의 메인 뷰의 불투명도를 0으로 설정하면 원래 니브에서 항목이 가려지지 않습니다.

이 질문의 근원이 되는 스탠드 아론 XIB의 작성 방법을 설명하는 답변은 없습니다.Xcode 4[ Create New XIB File ]신규 XIB 파일 작성하기

이렇게 하려면

1) Choose "New File..."
2) Choose the "User Interface" category under the iOS section
3) Choose the "View" item
4) You will then be prompted to choose an iPhone or iPad format

간단해 보이지만 XIB라는 단어는 어디에도 나타나지 않기 때문에 몇 분 동안 찾을 수 있습니다.

많은 시간을 보낸 후, 나는 다음과 같은 해결책을 고안해 냈다. 단계에 따라 커스텀을 .UIView.

1) UIView에서 상속받은 클래스 myCustomView를 만듭니다.
여기에 이미지 설명 입력

2) myCustomView라는 이름의 .xib를 만듭니다.
여기에 이미지 설명 입력

3) .xib 파일 내에서 UIView 클래스를 변경하고 myCustomView 클래스를 할당합니다.
여기에 이미지 설명 입력

4) IBOutlet 작성
여기에 이미지 설명 입력

5) myCustomView* customView에 .xib를 로드합니다.다음 샘플 코드를 사용합니다.

myCustomView * myView = [[[NSBundle mainBundle] loadNibNamed:@"myCustomView" owner:self options:nil] objectAtIndex:0];
[myView.description setText:@"description"];

주의: 아직 문제가 해결되지 않은 고객에게는 myCustomView 샘플 프로젝트 링크를 제공합니다.

최단 버전:

RSFavoritePlaceholderView *favoritePlaceholderView = [[[NSBundle mainBundle] loadNibNamed:@"RSFavoritePlaceholderView" owner:self options:nil] firstObject];

뷰와 동일한 뷰가 포함된 xibs의 이름을 붙이는 규칙이 있습니다.뷰 컨트롤러와 동일합니다.그러면 반 이름을 코드로 쓸 필요가 없어.같은 이름의 nib 파일에서 UIView를 로드합니다.

MyView라고 하는 클래스의 예.

  • MyView라는 니브 파일을 만듭니다.인터페이스 빌더의 xib
  • Interface Builder에서 UIView를 추가합니다.클래스를 MyView로 설정합니다.원하는 대로 커스터마이즈하고 MyView 인스턴스 변수를 나중에 액세스하고 싶은 서브뷰에 연결합니다.
  • 코드로 다음과 같이 새 MyView를 만듭니다.

    MyView *myView = [MyView nib_viewFromNibWithOwner: 소유자];

이 카테고리는 다음과 같습니다.

@implementation UIView (nib)

+ (id) nib_viewFromNib {
    return [self nib_viewFromNibWithOwner:nil];
}

+ (id) nib_viewFromNibWithOwner:(id)owner {
    NSString *className = NSStringFromClass([self class]);
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:className owner:owner options:nil];
    UIView *view = nil;
    for(UIView *v in nib) {
        if ([v isKindOfClass:[self class]]) {
            view = v;
            break;
        }
    }
    assert(view != nil && "View for class not found in nib file");
    [view nib_viewDidLoad];
    return view;
}

// override this to do custom setup
-(void)nib_viewDidLoad {

}

그런 다음 사용 중인 컨트롤러의 동작과 버튼을 연결하고 커스텀 뷰 서브클래스의 콘센트를 사용하여 라벨에 내용을 설정합니다.

Swift 4에서 니브/xib에서 보기를 프로그래밍 방식으로 로드하려면:

// Load a view from a Nib given a placeholder view subclass
//      Placeholder is an instance of the view to load.  Placeholder is discarded.
//      If no name is provided, the Nib name is the same as the subclass type name
//
public func loadViewFromNib<T>(placeholder placeholderView: T, name givenNibName: String? = nil) -> T {

    let nib = loadNib(givenNibName, placeholder: placeholderView)
    return instantiateView(fromNib: nib, placeholder: placeholderView)
}

// Step 1: Returns a Nib
//
public func loadNib<T>(_ givenNibName: String? = nil, placeholder placeholderView: T) -> UINib {
    //1. Load and unarchive nib file
    let nibName = givenNibName ?? String(describing: type(of: placeholderView))

    let nib = UINib(nibName: nibName, bundle: Bundle.main)
    return nib
}

// Step 2: Instantiate a view given a nib
//
public func instantiateView<T>(fromNib nib: UINib, placeholder placeholderView: T) -> T {
    //1. Get top level objects
    let topLevelObjects = nib.instantiate(withOwner: placeholderView, options: nil)

    //2. Have at least one top level object
    guard let firstObject = topLevelObjects.first else {
        fatalError("\(#function): no top level objects in nib")
    }

    //3. Return instantiated view, placeholderView is not used
    let instantiatedView = firstObject as! T
    return instantiatedView
}

이 때문에, UIView에 카테고리를 추가했습니다.

 #import "UIViewNibLoading.h"

 @implementation UIView (UIViewNibLoading)

 + (id) loadNibNamed:(NSString *) nibName {
    return [UIView loadNibNamed:nibName fromBundle:[NSBundle mainBundle] retainingObjectWithTag:1];
 }

 + (id) loadNibNamed:(NSString *) nibName fromBundle:(NSBundle *) bundle retainingObjectWithTag:(NSUInteger) tag {
    NSArray * nib = [bundle loadNibNamed:nibName owner:nil options:nil];
    if(!nib) return nil;
    UIView * target = nil;
    for(UIView * view in nib) {
        if(view.tag == tag) {
            target = [view retain];
            break;
        }
    }
    if(target && [target respondsToSelector:@selector(viewDidLoad)]) {
        [target performSelector:@selector(viewDidLoad)];
    }
    return [target autorelease];
 }

 @end

여기서 설명: 뷰 컨트롤러의 ios&mac에서의 뷰 로딩이 적음

언급URL : https://stackoverflow.com/questions/863321/how-to-load-a-uiview-using-a-nib-file-created-with-interface-builder

반응형