uiview - use - xcode ui




Reutilizar um uiview xib no storyboard (5)

Atualização rápida 3 e 4 para a resposta aceita

1. Crie um novo UIView chamado 'DesignableXibView'

  • Arquivo> Novo> Arquivo> Origem> Cocoa Touch Class> UIView

2. Crie um arquivo xib correspondente chamado 'DesignableXibView'

  • Arquivo> Novo> Arquivo> Interface do Usuário> Exibir

3. Defina o proprietário do arquivo do xib

Selecione "DesignableXibView.xib"> "Proprietário do arquivo"> ​​defina "Classe personalizada" como 'DesignableXibView' no Identity Inspector.

  • Nota: Não configure a classe customizada da visualização no xib. Somente o proprietário do arquivo!

4. Implementação do DesignableXibView

    import UIKit

@IBDesignable

class DesignableXibView: UIView {

    var contentView : UIView!

    override init(frame: CGRect) {
        super.init(frame: frame)
        xibSetup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        xibSetup()
    }

    func xibSetup() {
        contentView = loadViewFromNib()

        // use bounds not frame or it'll be offset
        contentView.frame = bounds

        // Make the view stretch with containing view
        contentView.autoresizingMask = [UIViewAutoresizing.flexibleWidth, UIViewAutoresizing.flexibleHeight]

        // Adding custom subview on top of our view 
        addSubview(contentView)
    }

    func loadViewFromNib() -> UIView! {

        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
        let view = nib.instantiate(withOwner: self, options: nil).first as! UIView

        return view
    }
} 

5 Teste sua exibição reutilizável em um storyboard

  • Abra seu storyboard

  • Adicionar uma vista

  • Definir a classe personalizada dessa exibição

Normalmente, gosto de criar e projetar minhas uiviews no construtor de interfaces. Às vezes, preciso criar uma única exibição em um xib que possa ser reutilizada em vários controladores de exibição em um storyboard.


Para quem tenta adaptar a resposta aceita (por @Garfbargle) ao Objective-C

Apenas converter Swift para Objective-C não é suficiente para fazê-lo funcionar. Tive dificuldade para permitir a renderização ao vivo no Storyboard.

Depois de traduzir o código inteiro, a exibição fica bem carregada ao executar no dispositivo (ou simulador), mas a renderização ao vivo no Storyboard não funciona. A razão para isso é que eu usei [NSBundle mainBundle] enquanto o Interface Builder não tem acesso ao mainBundle. O que você precisa usar é [NSBundle bundleForClass:self.classForCoder] . BOOM, a renderização ao vivo funciona agora!

Nota: se você tiver problemas com o Layout automático, tente desativar os Safe Area Layout Guides no Xib.

Para sua conveniência, deixo meu código inteiro aqui, para que você apenas precise copiar / colar (para todo o processo, siga a resposta original ):

BottomBarView.h

#import <UIKit/UIKit.h>

IB_DESIGNABLE
@interface BottomBarView : UIView

@end

BottomBarView.m

#import "BottomBarView.h"

@interface BottomBarView() {
    UIView *contentView;
}

@end


@implementation BottomBarView

-(id) initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self xibSetup];
    }
    return self;
}

-(id) initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self xibSetup];
    }
    return self;
}

-(void) xibSetup {
    contentView = [self loadViewFromNib];

    contentView.frame = self.bounds;

    contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

    [self addSubview:contentView];
}

-(UIView*) loadViewFromNib {
    NSBundle *bundle = [NSBundle bundleForClass:self.classForCoder]; //this is the important line for view to render in IB
    UINib *nib = [UINib nibWithNibName:NSStringFromClass([self class]) bundle:bundle];
    UIView *view = [nib instantiateWithOwner:self options:nil][0];

    return view;
}

@end

Diga-me se você encontrar alguns problemas, mas ele quase funcionará imediatamente :)


A função initWithCoder no swift 2 se alguém tiver problemas para convertê-la:

required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        UINib(nibName: String(self.dynamicType), bundle: NSBundle.mainBundle()).instantiateWithOwner(self, options: nil)
        self.addSubview(view)
        self.view.translatesAutoresizingMaskIntoConstraints = false
        self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[view]|", options: NSLayoutFormatOptions.AlignAllCenterY , metrics: nil, views: ["view": self.view]))
        self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[view]|", options: NSLayoutFormatOptions.AlignAllCenterX , metrics: nil, views: ["view": self.view]))
    }

Aqui está a resposta que você sempre quis. Você pode apenas criar sua classe CustomView , ter a instância principal dela em um xib com todas as subvisões e saídas. Em seguida, você pode aplicar essa classe a quaisquer instâncias em seus storyboards ou outros xibs.

Não há necessidade de mexer com o proprietário do arquivo, ou conectar tomadas a um proxy ou modificar o xib de uma maneira peculiar ou adicionar uma instância de sua visualização personalizada como uma sub-visualização própria.

Apenas faça o seguinte:

  1. Importar estrutura BFWControls
  2. Altere sua superclasse de UIView para NibView (ou de UITableViewCell para NibTableViewCell )

É isso aí!

Ele ainda funciona com o IBDesignable para renderizar sua visualização personalizada (incluindo as subvisões do xib) em tempo de design no storyboard.

Você pode ler mais sobre isso aqui: https://medium.com/build-an-app-like-lego/embed-a-xib-in-a-storyboard-953edf274155

E você pode obter a estrutura BFWControls de código aberto aqui: https://github.com/BareFeetWare/BFWControls

Tom 👣


NOVO! resposta atualizada com capacidade de renderizar diretamente no storyboard (e rápido!)

Funciona no Xcode 6.3.1

Crie um novo UIView chamado 'ReuseableView'

  • Arquivo> Novo> Arquivo> Origem> Cocoa Touch Class> UIView

Crie um arquivo xib correspondente chamado 'ReuseableView'

  • Arquivo> Novo> Arquivo> Interface do Usuário> Exibir

Defina o proprietário do arquivo do xib

  1. selecione o xib
  2. selecione o proprietário do arquivo
  3. defina a classe personalizada como 'ReusableView' no Identity Inspector.

    • Nota: Não configure a classe customizada da visualização no xib. Somente o proprietário do arquivo!

Faça uma saída da exibição no ReuseableView.xib para a interface ReuseableView.h

  1. Open Assistant Editor
  2. Control + Arraste da visualização para a sua interface

Adicione a implementação initWithCoder para carregar a visualização e adicionar como uma subvisão.

- (id)initWithCoder:(NSCoder *)aDecoder{
    self = [super initWithCoder:aDecoder];
    if (self) {

        // 1. load the interface
        [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil];
        // 2. add as subview
        [self addSubview:self.view];
        // 3. allow for autolayout
        self.view.translatesAutoresizingMaskIntoConstraints = NO;
        // 4. add constraints to span entire view
        [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view]|" options:0 metrics:nil views:@{@"view":self.view}]];
        [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view]|" options:0 metrics:nil views:@{@"view":self.view}]];

    }
    return self;
}

Teste sua visão reutilizável em um storyboard

  1. Abra seu storyboard
  2. Adicionar uma vista
  3. Definir a classe personalizada dessa exibição

Corra e observe!





xib