আমি কীভাবে সুইফটে কোনও ইউআইভিউকন্ট্রোলার সাবক্লাসের জন্য কাস্টম ইনিশিয়ালাইজার করব?


95

যদি এর আগে জিজ্ঞাসা করা হত তবে দুঃখিত, আমি প্রায় অনেক অনুসন্ধান করেছি এবং যখন জিনিসগুলি আলাদা ছিল তখন অনেক উত্তর পূর্ববর্তী সুইফ্ট বিটা থেকে পাওয়া যায়। আমি একটি নির্দিষ্ট উত্তর খুঁজে পেতে পারে না।

আমি সাবক্লাস করতে চাই UIViewControllerএবং একটি কাস্টম ইনিশিয়ালাইজার পেয়েছি যাতে আমাকে কোডে সহজেই সেট আপ করতে দেয়। সুইফটে এটি করতে আমার সমস্যা হচ্ছে।

আমি একটি init()ফাংশন চাই যা আমি একটি নির্দিষ্ট পাস করতে ব্যবহার করতে NSURLপারি তারপরে আমি ভিউ কন্ট্রোলারের সাথে ব্যবহার করব। মনে মনে এমন কিছু লাগছে init(withImageURL: NSURL)। আমি যদি সেই ফাংশনটি যুক্ত করি তবে তা আমাকে init(coder: NSCoder)ফাংশনটি যুক্ত করতে বলে ।

আমি বিশ্বাস করি এটি হ'ল কারণ এটি মূলশব্দটি সুপারক্লাসে চিহ্নিত হয়েছে required? সুতরাং আমি এটা সাবক্লাসে করতে হবে? আমি এটি যুক্ত:

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

এখন কি? আমার বিশেষ প্রারম্ভিক convenienceএক বিবেচনা করা হয়? একটি মনোনীত? আমি কি একটি সুপার ইনিশিয়ালাইজার কল করব? একই ক্লাসের একজন ইনিশিয়ালাইজার?

আমি কীভাবে UIViewControllerসাবক্লাসে আমার বিশেষ প্রারম্ভিককে যুক্ত করব ?


প্রবর্তকরা প্রোগ্রামগতভাবে তৈরি ভিউ কনট্রোলারদের পক্ষে ভাল তবে স্টোরিবোর্ডের মাধ্যমে তৈরি করা ভিউকন্ট্রোলারদের পক্ষে আপনার ভাগ্য খুব খারাপ এবং এটিকে ঘিরে আপনার পথ চালিয়ে যেতে হবে
হানি

উত্তর:


161
class ViewController: UIViewController {

    var imageURL: NSURL?

    // this is a convenient way to create this view controller without a imageURL
    convenience init() {
        self.init(imageURL: nil)
    }

    init(imageURL: NSURL?) {
        self.imageURL = imageURL
        super.init(nibName: nil, bundle: nil)
    }

    // if this view controller is loaded from a storyboard, imageURL will be nil

    /* Xcode 6
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    */

    // Xcode 7 & 8
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}

পরিবর্তে চিত্রের URL স্থির হতে পারে? ("চিত্র চিত্রটি দেওয়া যাক: এনএসআরএল?)
ভ্যান ডু ট্রান

4
এক্সকোড working কাজ করছে না, প্রয়োজনীয় কনস্ট্রাক্টর ক্লাস স্তরের সম্পত্তি আরম্ভ করতে ব্যর্থ হচ্ছে, আমার ক্ষেত্রে এনটিআরএল নয়, কোন এনটিআরএল?
ক্রিস হেইস

4
@NikolaLukic - আমরা কল করে ক্লাসের একটি নতুন দৃষ্টান্ত সৃষ্টি করতে ViewController(), ViewController(imageURL: url), অথবা এটি একটি স্টোরিবোর্ড থেকে লোড।
ylin0x81

4
আমাকে required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }অন্যথায় যেমন লিখতে super.init(coder: aDecoder)হয়েছিল ততই আমি কলটি দিয়ে সম্পত্তিটিরself.somePropertysuper.init
হানি

4
কীভাবে এটি সম্পর্কিত তা নিশ্চিত নয়। আপনি যদি খাঁটি কোডটি করেন, তবে আপনাকে নিজের বৈশিষ্ট্যগুলির ভিতরে থাকা দরকার নেই init(coder: aDecoder)fatalErrorইচ্ছা চলা
মধু

26

যারা কোডে ইউআই লিখেন তাদের জন্য

class Your_ViewController : UIViewController {

    let your_property : String

    init(your_property: String) {
        self.your_property = your_property
        super.init(nibName: nil, bundle: nil)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) is not supported")
    }
}

12

এটি অন্যান্য উত্তরগুলির সাথে খুব মিল, তবে কিছু ব্যাখ্যা সহ। গৃহীত উত্তর বিভ্রান্তিকর কারণ এটির সম্পত্তি হয় ঐচ্ছিক এবং সত্য যে, আপনার দেখাবে না তা init?(coder: NSCoder)নয় প্রতিটি সম্পত্তি এবং যে একটি হচ্ছে না একমাত্র সমাধান আরম্ভ fatalError()। শেষ পর্যন্ত আপনি আপনার সম্পত্তি বিকল্পগুলি তৈরি করে পালিয়ে যেতে পারতেন, তবে এটি ওপির প্রশ্নের সত্যই উত্তর দেয় না।

// Think more of a OnlyNibOrProgrammatic_NOTStoryboardViewController
class ViewController: UIViewController {

    let name: String

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    // I don't have a nib. It's all through my code.
    init(name: String) {
        self.name = name

        super.init(nibName: nil, bundle: nil)
    }

    // I have a nib. I'd like to use my nib and also initialze the `name` property
    init(name: String, nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle? ) {
        self.name = name
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }

    // when you do storyboard.instantiateViewController(withIdentifier: "ViewController")
    // The SYSTEM will never call this!
    // it wants to call the required initializer!

    init?(name: String, coder aDecoder: NSCoder) {
        self.name = "name"
        super.init(coder: aDecoder)
    }

    // when you do storyboard.instantiateViewController(withIdentifier: "ViewController")
    // The SYSTEM WILL call this!
    // because this is its required initializer!
    // but what are you going to do for your `name` property?!
    // are you just going to do `self.name = "default Name" just to make it compile?!
    // Since you can't do anything then it's just best to leave it as `fatalError()`
    required init?(coder aDecoder: NSCoder) {
        fatalError("I WILL NEVER instantiate through storyboard! It's impossible to initialize super.init?(coder aDecoder: NSCoder) with any other parameter")
    }
}

আপনাকে মূলত স্টোরিবোর্ড থেকে এটি লোড করতে হবে। কেন?

কারণ আপনি যখন একটি ভিউকন্ট্রোলার কল করবেন storyboard.instantiateViewController(withIdentifier: "viewController")তখন ইউআইকিট এটি করবে এবং কল করবে

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

আপনি কখনই এই কলটি অন্য আরম্ভ পদ্ধতিতে পুনর্নির্দেশ করতে পারবেন না।

দস্তাবেজগুলি instantiateViewController(withIdentifier:):

প্রোগ্রামটিমেটিকভাবে উপস্থাপন করতে ভিউ কন্ট্রোলার অবজেক্ট তৈরি করতে এই পদ্ধতিটি ব্যবহার করুন। প্রতিবার আপনি এই পদ্ধতিটিকে কল করুন, এটি init(coder:)পদ্ধতিটি ব্যবহার করে দর্শন নিয়ামকের একটি নতুন উদাহরণ তৈরি করে ।

তবুও প্রোগ্রামগতভাবে তৈরি ভিউ কন্ট্রোলার বা নিব তৈরি ভিউ কন্ট্রোলারদের জন্য আপনি উপরের চিত্রের মতো কলটি পুনর্নির্দেশ করতে পারেন।


5

সুবিধাপ্রাপ্তি প্রাথমিককরণগুলি মাধ্যমিক হয়, একটি শ্রেণীর জন্য প্রাথমিক সাহায্যকারী। ডিফল্ট মানগুলিতে সেট করা কিছু নির্ধারিত প্রাথমিকের প্যারামিটারের সাথে সুবিধাপূর্ণ প্রাথমিক হিসাবে একই শ্রেণি থেকে একটি মনোনীত প্রারম্ভিককে কল করতে আপনি কোনও সুবিধাপূর্ণ আরম্ভকারীকে সংজ্ঞায়িত করতে পারেন। নির্দিষ্ট শ্রেণীর ক্ষেত্রে ব্যবহারের ক্ষেত্রে বা ইনপুট মানের ধরণের জন্য আপনি সেই শ্রেণীর উদাহরণ তৈরি করতে কোনও সুবিধাপূর্ণ প্রাথমিককরণকে সংজ্ঞায়িত করতে পারেন।

তারা এখানে নথিভুক্ত করা হয়


0

উদাহরণস্বরূপ পপওভারের জন্য আপনার যদি কাস্টম উদ্যোগের প্রয়োজন হয় আপনি নীচের পদ্ধতিটি ব্যবহার করতে পারেন:

একটি কাস্টম থিম তৈরি করুন যা নিবনেম এবং বান্ডিল সহ সুপার থ্রি ব্যবহার করে এবং তারপরে ভিউয়ের স্তরক্রমের লোডকে বাধ্য করতে ভিউ সম্পত্তিটিতে অ্যাক্সেস করে।

তারপরে ভিউডিডলড ফাংশনে আপনি আদিতে পাস হওয়া প্যারামিটারগুলি দিয়ে ভিউগুলি কনফিগার করতে পারেন।

import UIKit

struct Player {
    let name: String
    let age: Int
}

class VC: UIViewController {


@IBOutlet weak var playerName: UILabel!

let player: Player

init(player: Player) {
    self.player = player
    super.init(nibName: "VC", bundle: Bundle.main)
    if let view = view, view.isHidden {}
}

override func viewDidLoad() {
    super.viewDidLoad()
    configure()
}

func configure() {
    playerName.text = player.name + "\(player.age)"
}
}

func showPlayerVC() {
    let foo = Player(name: "bar", age: 666)
    let vc = VC(player: foo)
    present(vc, animated: true, completion: nil)
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.