This AssetRFPViewController class call a custom view(AssetBasicInfo) in viewDidLoad, if a pass "Hello" its ok but when i pass object to custom view(AssetBasicInfo) its not taken, How can i design a custom view class so its catch object
class AssetRFPViewController: UIViewController
{
var asset:Asset = Asset()
override func viewDidLoad() {
let customView = AssetBasicInfo(frame: self.topHeaderView.bounds)
customView.assetNameValLbl.text = "Hello" // ok
customView.assetObj = self.asset // not ok, passing object
self.topHeaderView.addSubview(customView)
}
}
Now my custom class look like this,
class AssetBasicInfo: UIView {
#IBOutlet var containerView: UIView!
var assetObj:Asset = Asset() // i want value in this object "assetObj"
#IBOutlet var assetNameValLbl: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
print(frame.size.width)
print(frame.size.height)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder : aDecoder)
commonInit()
}
private func commonInit(){
Bundle.main.loadNibNamed("HeaderViewXIB", owner: self, options: nil)
self.addSubview(containerView)
self.containerView.frame = self.frame
containerView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
self.assetNameValLbl.text = assetObj.name // not setting value
print("screenName" , screenName)
}
}
Related
IBOutlets in CustomView are coming as nil.
I have created Custom view(xib).
Please find images for more information.
class TextFieldView: UIView {
#IBOutlet var contentView: TextFieldView!
#IBOutlet weak var customTextField: UITextField!
#IBOutlet weak var rightButton: UIButton!
#IBOutlet weak var placeHolderLabel: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
override func awakeFromNib() {
super.awakeFromNib()
}
func commonInit()
{
let bundle = Bundle(for: type(of: self))
bundle.loadNibNamed("TextFieldView", owner: self, options: nil)
customTextField.backgroundColor = UIColor.green
NSLog("Called")
}
Still throwing an error with exc_bad_access.(In loadNibNamed line of code)
Swift 3 Version
This is the solution that worked for me. Make sure your file object in IB has the TextFieldView Class assigned to it (not the UIView itself). Also make sure all your IBOutlets are connected to the right place or you risk running into trouble.
class TextFieldView: UIView {
#IBOutlet var contentView: TextFieldView!
#IBOutlet weak var customTextField: UITextField!
#IBOutlet weak var rightButton: UIButton!
#IBOutlet weak var placeHolderLabel: UILabel!
override init (frame: CGRect) {
super.init(frame: frame)
commonInit()
}
//This lets us use TextFieldView in IB
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
private func commonInit() {
Bundle(for: TextFieldView.self).loadNibNamed("TextFieldView", owner: self, options: nil)
//Positioning content so it fills view space
contentView.frame = self.bounds
contentView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
addSubview(contentView)
}
You need something like:
/// This view must be connected with the main view of the XIB.
#IBOutlet private var view: UIView!
/// This method is used when creating an `ApexView` with code.
override init(frame: CGRect)
{
super.init(frame: frame)
initView()
}
/// This method is called when instantiated from a XIB.
required init?(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)
initView()
}
private func initView()
{
/// Fill in the name of your XIB. I assumed it `"TextFieldView"`.
Bundle.main.loadNibNamed("TextFieldView", owner: self, options: nil)
self.view.frame = CGRect(x: 0.0, y: 0.0, width: self.width, height: self.height)
self.addSubview(self.view!)
...
}
I have been trying to figure this out for days and haven't had much luck :(
What I want to do is set the variable inside of an instance of a XIB (called BottomNav) that already exists in another ViewController, called "curX". I have come the closest with the following:
class Util: NSObject {
class func loadNib() {
let nib: BottomNav = Bundle.main.loadNibNamed("BottomNav", owner: self, options: nil)!.first as! BottomNav
nib.curX = 10
}
}
Here is the BottomNav Class:
class BottomNav: UIView {
#IBOutlet var view: UIView!
#IBOutlet weak var homeBtn: UIView!
#IBOutlet weak var scroller: UIScrollView!
#IBOutlet weak var scrollerContent: UIView!
var curX = 32
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
Bundle.main.loadNibNamed("BottomNav", owner: self, options: nil)
self.addSubview(self.view)
}
}
This passes the compiler with no warnings, but when it's ran I get a "this class is not key value coding-compliant for the key" error. This usually appears when there's an outlet that no longer exists, but this is definitely not the case, I've tested it with multiple XIBs that are already on the app, and had no problem loading in the first place via storyboards. I only get this error with "loadNibNamed".
Am I even on the right path here? My thought is maybe my Util class doesn't have access to Bundle or something?
class BottomNav: UIView {
#IBOutlet var view: UIView!
#IBOutlet weak var homeBtn: UIView!
#IBOutlet weak var scroller: UIScrollView!
#IBOutlet weak var scrollerContent: UIView!
var curX = 32
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
func commonInit(){
Bundle.main.loadNibNamed("BottomNav", owner: self, options: nil)
guard let content = view else { return }
content.frame = self.bounds
content.autoresizingMask = [.flexibleHeight, .flexibleWidth]
self.addSubview(content)
}
}
And when calling the instance, try the following.
let instance = BottomNav()
instance.curX = 30
Swift 3.0
I Think you get you solution from this. All the best
var view: UIView!
override init(frame: CGRect) {
// call super.init(frame:)
super.init(frame: frame)
// 3. Setup view from .xib file
xibSetup()
}
required init?(coder aDecoder: NSCoder) {
// call super.init(coder:)
super.init(coder: aDecoder)
// 3. Setup view from .xib file
xibSetup()
}
// MARK: - UI setup
func xibSetup() {
let nib = UINib(nibName: "BottomNav", bundle: nil)
view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView
// use bounds not frame or it'll be offset
view.frame = bounds
// Make the view stretch with containing view
view.autoresizingMask = [UIViewAutoresizing.flexibleWidth, UIViewAutoresizing.flexibleHeight]
addSubview(view)
}
class MyClass {
let customView: MyView
init() {
customView = MyView()
customView.checkBox.addTarget(self, action: #selector(checkBoxValueChanged(_:)), for: .valueChanged)
}
#objc func checkBoxValueChanged(_ sender: M13Checkbox!) {
print("checkBoxValueChanged")
}
}
#IBDesignable class MyView: UIView {
#IBOutlet var view: UIView!
#IBOutlet var checkBox: M13Checkbox!
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupView()
}
func setupView() {
let bundle = Bundle(for: type(of: self))
UINib(nibName: Constant.xib.MY_XIB, bundle: bundle).instantiate(withOwner: self, options: nil)
view.frame = bounds
view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
addSubview(view)
}
}
I want to manage an event in MyClass but the selector is not called.
If I do the same logic in UIViewController it works, but not in this case. Can anyone help me? Thanks
I have created a custom UIView in xib with class InfoPopUpView. I add it to my viewController. It works well and the Custom Class xib is set in the File's Owner.
I can set the titleLbl variable in my first viewcontroller no problem.
My problem appears when I in another viewcontroller want to use the InfoPopUpView again but with a different title...
The title does not change/update. It is as if InfoPopUpView remembers the last title I set and dont care for changing it..
How can I initialise? the titleLbl variable in the InfoPopUpView Class so that I can change it later?
Any help is very much appreciated - thank you !
ViewController
var popUpView: InfoPopUpView!
popUpView = InfoPopUpView(frame: CGRectMake(0, 0, 300, 268))
popUpView.titleLbl.text = "MyFirstTitle"
view.addSubview(popUpView)
Custom Class
class InfoPopUpView: UIView {
var view: UIView!
#IBOutlet weak var okBtn: UIButton!
#IBOutlet weak var titleLbl: UILabel!
#IBOutlet weak var textView: UITextView!
#IBAction func didTapOkBtn(sender: AnyObject) {
NSNotificationCenter.defaultCenter().postNotificationName("popUpController", object: nil)
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
func setup() {
view = loadViewFromNib()
view.frame = bounds
view.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight]
addSubview(view)
}
func loadViewFromNib() -> UIView {
let bundle = NSBundle(forClass: self.dynamicType)
let nib = UINib(nibName: "InfoPopUpView", bundle: bundle)
let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView
return view
}
}
When I try to use this custom control within my main view controller, by dragging a UIView onto screen in IB and setting it to "CustomerControlView", it doesn't actually show it.
Question - What is wrong with the code I have here?
Background - So wanting to basically:
a) design a customer control in IB
b) so I'm assuming I create the NIB file and then create a UIView file, so this is what I've done
Screenshot of NIB & swift file
Code
import UIKit
class CustomControlView: UIView {
// #IBOutlet var icon: UIImageView!
// #IBOutlet weak var view: UIView!
#IBOutlet weak var button: UIButton!
#IBOutlet weak var text1: UITextField!
#IBOutlet weak var text2: UITextField!
override init(frame: CGRect) {
print("override init(frame: CGRect) ")
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
print("required init?(coder aDecoder: NSCoder)")
super.init(coder: aDecoder)
// let arr = NSBundle.mainBundle().loadNibNamed("CustomControlView", owner: nil, options: nil)
// let v = arr[0] as! UIView
// self.view.addSubview(v)
}
}
Snapshot showing how I have included the custom view into my main viewController view:
Just add #IBDesignable above the class line to tell Xcode to compile it before showing it in storyboard. There is a great discussion on this subject here: http://nshipster.com/ibinspectable-ibdesignable/
Also, you need to make sure that the NIB is being loaded:
override init(frame: CGRect) {
print("override init(frame: CGRect) ")
super.init(frame: frame)
xibSetup()
}
required init?(coder aDecoder: NSCoder) {
print("required init?(coder aDecoder: NSCoder)")
super.init(coder: aDecoder)
xibSetup()
}
func xibSetup() {
view = loadViewFromNib()
view.frame = bounds
view.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
addSubview(view)
}
func loadViewFromNib() -> UIView {
let bundle = NSBundle(forClass: self.dynamicType)
let nib = UINib(nibName: "CustomNumberPad", bundle: bundle)
let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView
return view
}