Sunday, September 11, 2016

Create a view from a .xib file easily

I always forget the underlying details of creating a view from a .xib file.

Bundle.instantiateNibWithName("MyNibName") as! MyNib // uhhh, what??

😩 That is what I normally end up writing on the first stab... Clearly that is completely wrong. I wish there was a way to get the .xib to a UIView subclass in a much less complicated way. And THERE IS! 😁

Just have your UIView subclass conform to NibInstantiating and you just have to remember the very intuitive words viewFromNib rather than Bundle(for: TheClass.self).loadNibNamed("UghAString", owner: nil, options: nil).

class TextInputBar: UIView, NibInstantiating {
to instantiate, just call viewFromNib

let inputBar = TextInputBar.viewFromNib()

Isn't that so much nicer on the brain!?

Here's the protocol and extension:


protocol NibInstantiating: class {
    static var nibName: String { get }
}

extension NibInstantiating {
    
    static func viewFromNib() -> Self! {
        var view: Self!
        let objects = Bundle(for: self).loadNibNamed(nibName, owner: nil, options: nil)
        for object in objects! {
            guard let foundView = object as? Self else { continue }
            view = foundView
            break
        }
        assert(view != nil, "Could not find object of type: \(Self.self) \(#function)")
        return view
    }
    
    static var nibName: String { return String(describing: Self.self) }

}


To download the code, click here: NibInstantiating.

Wednesday, September 7, 2016

Adjust UITableView for Keyboard in Swift

You've got a table full of cells. Now you add a text input of some kind. I used to avoid this whenever possible because it was so aggravating trying to show the last few cells above the keyboard. I used to do something similar every time, but it always changed a little and there were always annoying bugs that never seemed to die.

`TableViewInsetsAdjusting` to the rescue!

final class ExampleTableViewController: UITableViewController, TableViewInsetsAdjusting {
    
    private var inputBar: TextInputBar = TextInputBar.viewFromNib()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupInsetAdjust()
    }
    
    override func canBecomeFirstResponder() -> Bool {
        return true
    }
    
    override var inputAccessoryView: UIView? {
        return inputBar
    }
    
    deinit {
        takeDownInsetAdjust()
    }
    
}

Just conform to TableViewInsetsAdjusting, call `setupInsetAdjust` and you'll have your insets adjusting automatically for you whenever the keyboard comes up.

Don't forget to call `takeDownInsetAdjust` on your way out.

That's it!!! All your problems are now solved!

Here's the repo: TableViewInsetsAdjusting Repo