কীভাবে সুইফটে এক্সআইবি ফাইল সহ একটি কাস্টম ইউআইভিউ ক্লাস শুরু / ইনস্ট্যান্টিয়েট করবেন


139

আমার একটি ক্লাস রয়েছে MyClassযা একটি সাবক্লাস UIView, যা আমি একটি XIBফাইল দিয়ে আরম্ভ করতে চাই । এই ক্লাসটি কীভাবে xib ফাইল বলা হয় তা দিয়ে কীভাবে সূচনা করা যায় তা আমি নিশ্চিত নইView.xib

class MyClass: UIView {

    // what should I do here? 
    //init(coder aDecoder: NSCoder) {} ?? 
}

5
iOS9 সুইফট জন্য পূর্ণ সোর্স কোড নমুনা 2.0 পড়ুন github.com/karthikprabhuA/CustomXIBSwift ও সংশ্লিষ্ট থ্রেড stackoverflow.com/questions/24857986/...
karthikPrabhu Alagu

উত্তর:


266

আমি এই কোডটি পরীক্ষা করেছি এবং এটি দুর্দান্ত কাজ করে:

class MyClass: UIView {        
    class func instanceFromNib() -> UIView {
        return UINib(nibName: "nib file name", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as UIView
    }    
}

ভিউটি আরম্ভ করুন এবং নীচের মতো ব্যবহার করুন:

var view = MyClass.instanceFromNib()
self.view.addSubview(view)

অথবা

var view = MyClass.instanceFromNib
self.view.addSubview(view())

আপডেট আপডেট> = 3.x এবং সুইফট> = 4.x

class func instanceFromNib() -> UIView {
    return UINib(nibName: "nib file name", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! UIView
}

1
এটি হবে var view = MyClass.instanceFromNib()& self.view.addSubview(view)হিসাবে বিরোধিতা var view = MyClass.instanceFromNib& self.view.addSubview(view())। উত্তরটি উন্নত করার জন্য কেবল একটি ছোট্ট পরামর্শ :)
লোগান

1
আমার ক্ষেত্রে দেখুন পরে আরম্ভ করা! যদি এটি সেলফ.ভিউ.অ্যাডসুবউভিউ (ভিউ) হয় তবে ভিউটি ভিউ হওয়া উচিত = MyClass.instanceFromNib ()
এজিমেট

2
@ এজিমেট এই ভিউয়ের ভিতরে থাকা আইবিএ ক্রিয়াকলাপগুলি সম্পর্কে কী বলবেন। কোথায় তাদের পরিচালনা করতে। যেমন আমার ভিউতে একটি বোতাম রয়েছে (xib) কীভাবে সেই বোতামটির আইবিএક્શન ক্লিক ইভেন্টটি পরিচালনা করতে হয়।?
কাদির হুসেন

6
এটি কি কেবলমাত্র ইউআইভিউয়ের পরিবর্তে "মাইক্লাস" ফেরত দেওয়া উচিত?
কেসং জি

2
আইব্লটলেটগুলি এই পদ্ধতিতে কাজ করছে না ... আমি পেয়ে যাচ্ছি: "এই শ্রেণিটি কীটির মূল কোডিং-অনুকরণকারী নয়"
রাদেক উইলকাক

82

স্যামের সমাধান ইতিমধ্যে দুর্দান্ত it

আপনি যদি আপনার জিবি আউটলেটগুলির জন্য সম্পূর্ণ সমর্থন চান, বিভিন্ন বান্ডিল (ফ্রেমওয়ার্কগুলিতে ব্যবহার করুন!) এবং স্টোরিবোর্ডে একটি সুন্দর প্রাকদর্শন পেতে চেষ্টা করুন:

// NibLoadingView.swift
import UIKit

/* Usage: 
- Subclass your UIView from NibLoadView to automatically load an Xib with the same name as your class
- Set the class name to File's Owner in the Xib file
*/

@IBDesignable
class NibLoadingView: UIView {

    @IBOutlet weak var view: UIView!

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

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

    private func nibSetup() {
        backgroundColor = .clearColor()

        view = loadViewFromNib()
        view.frame = bounds
        view.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
        view.translatesAutoresizingMaskIntoConstraints = true

        addSubview(view)
    }

    private func loadViewFromNib() -> UIView {
        let bundle = NSBundle(forClass: self.dynamicType)
        let nib = UINib(nibName: String(self.dynamicType), bundle: bundle)
        let nibView = nib.instantiateWithOwner(self, options: nil).first as! UIView

        return nibView
    }

}

আপনার এক্সিবটি যথারীতি ব্যবহার করুন, অর্থাৎ ফাইলের মালিকের সাথে আউটলেটগুলি সংযুক্ত করুন এবং ফাইল মালিক শ্রেণিকে নিজের শ্রেণিতে সেট করুন।

ব্যবহার: কেবল নিবলয়েডভিউ থেকে আপনার নিজস্ব শ্রেণি সাবক্লাস করুন এবং ক্লাবের নামটি Xib ফাইলের ফাইলের মালিকের কাছে সেট করুন

আর কোনও অতিরিক্ত কোডের প্রয়োজন নেই।

ক্রেডিটগুলি যেখানে creditণের শর্ত রয়েছে: জিএইচ-এ ডেনহ্যাডলেস থেকে ছোটখাটো পরিবর্তন করে এটি জোর করে। আমার বক্তব্য: https://gist.github.com/winkelsdorf/16c481f274134718946328b6e2c9a4d8


8
এই সমাধান ব্রেক সংযোগ নালী (কারণ এটি একটি subview যেমন লোড দৃশ্য যোগ করা) এবং কলিং nibSetupথেকে init?(coder:)অসীম recursion কারণ হবে যদি এম্বেডিং NibLoadingViewএকটি XIB হবে।
redent84

3
@ redent84 আপনার মন্তব্য এবং ডাউনটাউটের জন্য ধন্যবাদ। আপনার যদি ২ য় চেহারা থাকে তবে এটি পূর্ববর্তী সাবভিউ প্রতিস্থাপন করা উচিত (কোনও নতুন উদাহরণের ভেরিয়েবল দেওয়া হয়নি)। আপনি অসীম পুনরাবৃত্তি সম্পর্কে ঠিক বলেছেন, আইবির সাথে লড়াই করে যদি বাদ দেওয়া উচিত।
ফ্রেডেরিক উইনকেলসডর্ফ

1
উল্লিখিত হিসাবে "ফাইল মালিকের সাথে আউটলেটগুলি সংযুক্ত করুন এবং ফাইল মালিক শ্রেণিকে নিজের শ্রেণিতে সেট করুন" " আউটলেটগুলি ফাইলের মালিকের সাথে সংযুক্ত করুন
ইউসুফ এক্স

1
Xib থেকে ভিউ লোড করতে এই পদ্ধতিটি ব্যবহার করতে আমি সর্বদা অস্বস্তি বোধ করি। আমরা মূলত একটি ভিউ যুক্ত করছি যা ক্লাস এ এর ​​একটি সাবক্লাস, এমন একটি ভিউ যা ক্লাস এ এর ​​সাবক্লাসও রয়েছে এই পুনরাবৃত্তিটি রোধ করার কোনও উপায় নেই?
প্রজিৎ শ্রেষ্ঠ

1
স্ট্রিজবোর্ড .clearColor()থেকে লোড করার পরে @ প্রজিৎশ্রেষ্ঠ এটি সম্ভবত নিবসেটআপ () এর ব্যাকগ্রাউন্ড রঙ ওভাররাইড করার কারণে । এটি ইনস্ট্যান্ট হওয়ার পরে আপনি কোড দ্বারা এটি করেন তবে এটি কাজ করা উচিত। যাইহোক, যেমন আরও বেশি মার্জিত পন্থা হ'ল প্রোটোকল ভিত্তিক একটি। সুতরাং নিশ্চিত, আপনার জন্য এখানে একটি লিঙ্ক: github.com/AliSoftware/ পুনরায় ব্যবহারযোগ্য । আমি এখন ইউআইটিএবলভিউলেস (যা সত্যই কার্যকর প্রকল্পটি আবিষ্কার করার আগে আমি প্রয়োগ করেছি) সম্পর্কিত একটি অনুরূপ পন্থা ব্যবহার করছি। HTH!
ফ্রেডেরিক উইনকেলসডর্ফ

77

সুইফট ২.০ হিসাবে, আপনি একটি প্রোটোকল এক্সটেনশন যুক্ত করতে পারেন। আমার মতে, এটি আরও ভাল পদ্ধতির কারণ রিটার্নের ধরণটি Selfবরং তার চেয়ে ভাল UIView, সুতরাং কলারকে ভিউ ক্লাসে কাস্ট করার দরকার নেই।

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
  }

}

4
এটি নির্বাচিত উত্তরের চেয়ে ভাল সমাধান কারণ এখানে কাস্টিংয়ের প্রয়োজন নেই এবং এটি ভবিষ্যতে আপনি যে কোনও ইউআইভিউ সাবক্লাস তৈরি করেছেন তা পুনরায় ব্যবহারযোগ্য হবে।
ব্যবহারকারী3344977

3
আমি সুইফট ২.১ এবং এক্সকোড .2.২.১ দিয়ে চেষ্টা করেছি। এটি কিছু সময় কাজ করেছিল এবং অপ্রত্যাশিতভাবে অন্যদের সাথে মিটেক্স লক দিয়ে ঝুলিয়ে রাখত। কোডে সরাসরি ব্যবহৃত শেষ দুটি লাইন প্রতিবার শেষ লাইনের পরিবর্তিত var myView = nib.instantiate... as! myViewType
রূপরেখার

@ জুনিয়র-রুট-সিএস আপনার সম্পাদনাতে টাইপস / ত্রুটি রয়েছে, আমাকে এটি আবার রোল করতে হয়েছিল। এবং যাইহোক দয়া করে বিদ্যমান উত্তরগুলিতে কোড যুক্ত করবেন না। পরিবর্তে, একটি মন্তব্য করুন; অথবা আপনার নিজের উত্তরে আপনার সংস্করণ যুক্ত করুন । ধন্যবাদ।
এরিক আয়া

আমি Swift 3কোনও সমস্যা ছাড়াই (এক্সকোড ৮.০ বিটা)) ব্যবহার করে আমার প্রকল্পে যে কোডটি খোলার ও পরীক্ষিত করেছি তা পোস্ট করেছি । টাইপো ছিল Swift 2। এই উত্তরটি ভাল হলে এটি কেন অন্য উত্তর হওয়া উচিত এবং ব্যবহারকারীরা
এক্সসি

1
@ jr.root.cs হ্যাঁ এই উত্তরটি ভাল, তাই কারও এটিকে পরিবর্তন করা উচিত নয়। এটি স্যামের উত্তর, আপনার নয়। আপনি যদি এটিতে মন্তব্য করতে চান তবে একটি মন্তব্য দিন; আপনি যদি কোনও নতুন / আপডেট হওয়া সংস্করণ পোস্ট করতে চান তবে এটি নিজের পোস্টে করুন । সম্পাদনাগুলি বোঝানো হয় টাইপস / ইন্ডেন্টেশন / ট্যাগগুলি অন্য ব্যক্তির পোস্টগুলিতে আপনার সংস্করণগুলি যুক্ত না করার জন্য ঠিক করা। ধন্যবাদ।
এরিক আয়া

37

এবং এটি সুইফড 3.0 এ ফ্রেডেরিকের উত্তর

/*
 Usage:
 - make your CustomeView class and inherit from this one
 - in your Xib file make the file owner is your CustomeView class
 - *Important* the root view in your Xib file must be of type UIView
 - link all outlets to the file owner
 */
@IBDesignable
class NibLoadingView: UIView {

    @IBOutlet weak var view: UIView!

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

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

    private func nibSetup() {
        backgroundColor = .clear

        view = loadViewFromNib()
        view.frame = bounds
        view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        view.translatesAutoresizingMaskIntoConstraints = true

        addSubview(view)
    }

    private func loadViewFromNib() -> UIView {
        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
        let nibView = nib.instantiate(withOwner: self, options: nil).first as! UIView

        return nibView
    }
}

31

Xib থেকে ভিউ লোড করার সর্বজনীন উপায়:

উদাহরণ:

let myView = Bundle.loadView(fromNib: "MyView", withType: MyView.self)

বাস্তবায়ন:

extension Bundle {

    static func loadView<T>(fromNib name: String, withType type: T.Type) -> T {
        if let view = Bundle.main.loadNibNamed(name, owner: nil, options: nil)?.first as? T {
            return view
        }

        fatalError("Could not load view with type " + String(describing: type))
    }
}


26

সুইফট 3 উত্তর: আমার ক্ষেত্রে, আমি আমার কাস্টম ক্লাসে এমন একটি আউটলেট রাখতে চাই যা আমি সংশোধন করতে পারি:

class MyClassView: UIView {
    @IBOutlet weak var myLabel: UILabel!

    class func createMyClassView() -> MyClass {
        let myClassNib = UINib(nibName: "MyClass", bundle: nil)
        return myClassNib.instantiate(withOwner: nil, options: nil)[0] as! MyClassView
    }
}

.Xib এ থাকাকালীন কাস্টম ক্লাস ফিল্ডটি MyClassView নিশ্চিত করুন sure ফাইলের মালিককে বিরক্ত করবেন না।

কাস্টম ক্লাসটি মাইক্লাসভিউ নিশ্চিত করুন

এছাড়াও, নিশ্চিত হয়ে নিন যে আপনি মাইক্লাসভিউয়ের আউটলেটটিকে লেবেলে সংযুক্ত করেছেন: মাইবেল জন্য আউটলেট

এটি ইনস্ট্যান্ট করতে:

let myClassView = MyClassView.createMyClassView()
myClassView.myLabel.text = "Hello World!"

আমি "মাইক্লাস" নিব "ফিরে এসেছি তবে ভিউ আউটলেটটি সেট করা হয়নি" "যদি মালিক সেট না করা থাকে
jcharch

22

সুইফট 4

এখানে আমার ক্ষেত্রে আমাকে সেই কাস্টম ভিউতে ডেটা পাঠাতে হবে, তাই আমি ভিউটি ইনস্ট্যান্ট করার জন্য স্ট্যাটিক ফাংশন তৈরি করি।

  1. ইউআইভিউ এক্সটেনশন তৈরি করুন

    extension UIView {
        class func initFromNib<T: UIView>() -> T {
            return Bundle.main.loadNibNamed(String(describing: self), owner: nil, options: nil)?[0] as! T
        }
    }
  2. মাই কাস্টমভিউ তৈরি করুন

    class MyCustomView: UIView {
    
        @IBOutlet weak var messageLabel: UILabel!
    
        static func instantiate(message: String) -> MyCustomView {
            let view: MyCustomView = initFromNib()
            view.messageLabel.text = message
            return view
        }
    }
  3. .Xib ফাইলে মাইক্রাস্টমভিউতে কাস্টম ক্লাস সেট করুন। যথারীতি প্রয়োজনে আউটলেট সংযুক্ত করুন। এখানে চিত্র বর্ণনা লিখুন

  4. ইনস্ট্যানিয়েট দর্শন

    let view = MyCustomView.instantiate(message: "Hello World.")

যদি কাস্টম ভিউতে বোতামগুলি থাকে, তবে আমরা কীভাবে তাদের বিভিন্ন ক্রিয়াকলাপগুলিতে নিয়ন্ত্রণ করতে পারি?
জয়ন্ত কাবাত

আপনি প্রোটোকল-প্রতিনিধি ব্যবহার করতে পারেন। এখানে একবার দেখুন স্ট্যাকওভারফ্লো . com/ প্রশ্নগুলি / 29602612/…
mnemonic23

এটি এক্সবিতে একটি চিত্র লোড করতে ব্যর্থ হয়েছে, নিম্নলিখিত ত্রুটি পেয়েছে। সনাক্তকারী "টেস্ট.টেষ্টিং" সহ বান্ডলে একটি নিব থেকে রেফারেন্সযুক্ত " আইবিব্রোকেন ইমেজ" চিত্রটি লোড করা যায়নি
রবি রাজা জাঙ্গিদ

-4
override func draw(_ rect: CGRect) 
{
    AlertView.layer.cornerRadius = 4
    AlertView.clipsToBounds = true

    btnOk.layer.cornerRadius = 4
    btnOk.clipsToBounds = true   
}

class func instanceFromNib() -> LAAlertView {
    return UINib(nibName: "LAAlertView", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! LAAlertView
}

@IBAction func okBtnDidClicked(_ sender: Any) {

    removeAlertViewFromWindow()

    UIView.animate(withDuration: 0.4, delay: 0.0, options: .allowAnimatedContent, animations: {() -> Void in
        self.AlertView.transform = CGAffineTransform(scaleX: 0.1, y: 0.1)

    }, completion: {(finished: Bool) -> Void in
        self.AlertView.transform = CGAffineTransform.identity
        self.AlertView.transform = CGAffineTransform(scaleX: 0.0, y: 0.0)
        self.AlertView.isHidden = true
        self.AlertView.alpha = 0.0

        self.alpha = 0.5
    })
}


func removeAlertViewFromWindow()
{
    for subview  in (appDel.window?.subviews)! {
        if subview.tag == 500500{
            subview.removeFromSuperview()
        }
    }
}


public func openAlertView(title:String , string : String ){

    lblTital.text  = title
    txtView.text  = string

    self.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight)
    appDel.window!.addSubview(self)


    AlertView.alpha = 1.0
    AlertView.isHidden = false

    UIView.animate(withDuration: 0.2, animations: {() -> Void in
        self.alpha = 1.0
    })
    AlertView.transform = CGAffineTransform(scaleX: 0.0, y: 0.0)

    UIView.animate(withDuration: 0.3, delay: 0.2, options: .allowAnimatedContent, animations: {() -> Void in
        self.AlertView.transform = CGAffineTransform(scaleX: 1.1, y: 1.1)

    }, completion: {(finished: Bool) -> Void in
        UIView.animate(withDuration: 0.2, animations: {() -> Void in
            self.AlertView.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)

        })
    })


}

খারাপ ফর্ম্যাট কোড, ব্যাখ্যা নেই, তাই ডাউনভোট v
জে দো

এই প্রশ্নটির সাথে কী সম্পর্ক আছে?
অ্যাশলে মিলস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.