2

I’m trying to reuse a component from a xib in a Swift project, but I’m using Objective C logic. Thus, subclassing a view and loading the xib, then instantiating the custom view in the view controller.

Translating the code into Swift is not producing the results expected.


CustomView.swift:

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

required init(coder aDecoder: NSCoder) {

    super.init(coder: aDecoder)
    fatalError("Error detected")

    self.commonInit()
}

private func commonInit() {
    NSBundle.mainBundle().loadNibNamed("mainBar", owner: self, options: nil)
    self.addSubview(self)
}

viewController.swift:

var bottomBar : customView = customView(frame: CGRect(x: 0, y: 250, width: 250, height: 70))
  //bottomBar.backgroundColor = UIColor.redColor()
self.view.addSubview(bottomBar)

Objective-C I used as a reference:

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

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

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

    [self addSubview:self.view];
    }
    return self;
}

CustomView * myView = [CustomView alloc]init];
    [self.view addSubView:myView];

Any comment in the right direction is appreciated.

carlodurso
  • 2,886
  • 4
  • 24
  • 37

2 Answers2

2

Not 100 percent sure if your OBJ-C code actually work, but most probably don't. You have to realise that this [[NSBundle mainBundle] loadNibNamed:@"yourXib" owner:self options:nil]; returns always array of objects in your IB xib files. You actually don't assign this object anywhere as far as I see. The problem with this implementation might be frame that can be taken from bounds. This code works if we assume that there is only one object in an IB object.

private func commonInit()
{
    var nibView = NSBundle.mainBundle().loadNibNamed("mainBar", owner: self, options: nil)[0] as UIView
    nibView.frame = self.bounds;
    self.addSubview(nibView)
}
Vanya
  • 4,973
  • 5
  • 32
  • 57
  • thanks for your answer. You're correct on your initial assumption. I haven't tested that code in Objective-C. I've been unsuccessful with the code you provided, but I have the gut feeling that I'm not able to initialize the nib from a `UIView` subclass. A similar code is working when subclassing from a `UIViewController`. Can you shed some lights on how I could develop a [custom Tab Bar library](http://idevrecipes.com/2011/01/04/how-does-the-twitter-iphone-app-implement-a-custom-tab-bar/) in swift? – carlodurso Nov 24 '14 at 22:17
  • code is correct, there might a thing in IB you probably done other way and it is to make file owner of your class type and just let UIView (or any other basic object) that is coming with IB be as it is originally. Let me know if it helps. – Vanya Nov 25 '14 at 13:53
  • I agree with you, something wrong in my implementation. I actually ended up resolving by creating a UIView class that adds buttons programmatically, instead of using a xib. – carlodurso Dec 01 '14 at 01:40
2

You can try This

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

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

func loadViewFromNib() {

    let view = UINib(nibName: "CreditCardExperyView", bundle: NSBundle(forClass: self.dynamicType)).instantiateWithOwner(self, options: nil)[0] as! UIView

    view.frame = bounds

    view.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]

    self.addSubview(view);

}

 // Call subview 
 let creditCardView : CreditCardExperyView = CreditCardExperyView(frame: CGRect(x: 0, y: UIScreen.mainScreen().bounds.size.height - 280, width: UIScreen.mainScreen().bounds.size.width, height: 280))

 selfView.addSubview(creditCardView)
Anit Kumar
  • 8,075
  • 1
  • 24
  • 27