Swiftプロジェクトでxibファイルをロードする際に奇妙な問題があります。Obj-Cでそれを行う方法を既に知っているので、それはとてもイライラします。しかしSwift is Swiftですので、あなたがやったようにはできません..:/
だから、IconTextFiled.xibとIconTextField.Swiftを作成しました。 (UITextFieldを拡張)xibではIdenityインスペクターでフィールドクラスを入力し、ストーリーボードでは一部のtextFieldで同じ操作を行います。したがって、xibからの読み込みをinitメソッドに追加するだけでいいのでしょうか。番号。
Objcでは、このようにします
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"IconTextField" owner:self options:nil];
self = [nib objectAtIndex:0];
}
return self;
}
だから、Swiftに翻訳するといいと思います。
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
let nib:NSArray = NSBundle.mainBundle().loadNibNamed("IconTextField", owner: self, options: nil)
self = nib.objectAtIndex(0)
}
しかし、それはうまくいきません。理由はわかりませんが、より多くのオブジェクトを作成してクラッシュしようとします
最後に拡張機能を見つけました
extension IconTextField {
class func loadFromNibNamed(nibNamed: String, bundle : NSBundle? = nil) -> IconTextField? {
return UINib(
nibName: nibNamed,
bundle: bundle
).instantiateWithOwner(nil, options: nil)[0] as? IconTextField
}
}
したがって、ViewControllerでは次のようになります
@IBOutlet var password: IconTextField!
override func viewDidLoad() {
super.viewDidLoad()
password = IconTextField.loadFromNibNamed("IconTextField")
}
そして再び失敗します。 xibファイルをロードして使用する方法を教えてください。
ダニエル・アンサーの後を追う
私の現在のコード
class IconTextField: UITextField {
@IBOutlet var icon: UIImageView!
@IBOutlet weak var view: UIView!
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
NSLog("initWithCoder \(self)")
NSBundle.mainBundle().loadNibNamed("IconTextField", owner: self, options: nil)
self.addSubview(view)
}
}
これらの2つの変数は、これらのビューに接続されています
Consoleoの出力は非常に大きく、最後にEXC_BAD_ACCESS
2014-10-24 10:09:09.984 testproject[20337:3757479] initWithCoder <stensgroup.IconTextField: 0x7be7bfb0;>
2014-10-24 10:09:09.984 testproject[20337:3757479] initWithCoder <stensgroup.IconTextField: 0x7be7ddf0;>
2014-10-24 10:09:09.985 testproject[20337:3757479] initWithCoder <stensgroup.IconTextField: 0x7be7fa20;>
2014-10-24 10:09:09.985 testproject[20337:3757479] initWithCoder <stensgroup.IconTextField: 0x7be814f0;>
2014-10-24 10:09:09.986 testproject[20337:3757479] initWithCoder <stensgroup.IconTextField: 0x7be830c0;>
2014-10-24 10:09:10.083 testproject[20337:3757479] initWithCoder <stensgroup.IconTextField: 0x7d183270;>
2014-10-24 10:09:10.084 testproject[20337:3757479] initWithCoder <stensgroup.IconTextField: 0x7d187cd0;>
2014-10-24 10:09:10.084 testproject[20337:3757479] initWithCoder <stensgroup.IconTextField: 0x7d189960;>
InitWithCoderは2つだけです。 func loadNibNamedがinitWithCoder
を呼び出していることがわかります
これは私のために働く:
class IconTextField: UITextField {
@IBOutlet weak var view: UIView!
@IBOutlet weak var test: UIButton!
required init(coder: NSCoder) {
super.init(coder: coder)
NSBundle.mainBundle().loadNibNamed("IconTextField", owner: self, options: nil)
self.addSubview(view)
assert(test != nil, "the button is conected just like it's supposed to be")
}
}
1回loadNibNamed:owner:options:
はview
と呼ばれ、test
ボタンは予想通りコンセントに接続されます。ペン先のビューの自己のサブビュー階層を追加すると、ペン先のコンテンツが表示されます。
次のように、プロトコル拡張でloadFromNib()
関数を実装することにより、nibからロードすることを好みます。
(ここで説明されているとおり: https://stackoverflow.com/a/33424509/845027 )
import UIKit
protocol UIViewLoading {}
extension UIView : UIViewLoading {}
extension UIViewLoading where Self : UIView {
// note that this method returns an instance of type `Self`, rather than UIView
static func loadFromNib() -> Self {
let nibName = "\(self)".characters.split{$0 == "."}.map(String.init).last!
let nib = UINib(nibName: nibName, bundle: nil)
return nib.instantiateWithOwner(self, options: nil).first as! Self
}
}
これを使用できます:
if let customView = Bundle.main.loadNibNamed("MyCustomView", owner: self, options: nil)?.first as? MyCustomView {
// Set your view here with instantiated customView
}