আমি কীভাবে সুইফটে একটি ইউআইভিউ সাবক্লাসের জন্য কাস্টম উদ্যোগ লিখি?


125

বলুন আমি চাই initএকটি UIViewএকটি সঙ্গে উপশ্রেণী Stringএবং একটি Int

আমি যদি কেবল সাবক্লাসিং করছি তবে আমি কীভাবে সুইফটে এটি করব UIView? আমি যদি কেবল একটি কাস্টম init()ফাংশন করি তবে প্যারামিটারগুলি স্ট্রিং এবং একটি ইন্টার হয় তবে এটি আমাকে বলে যে "সুপার ইন্ডিটাইট () আরম্ভকারী থেকে ফেরার আগে ডাকা হয় না"।

এবং যদি আমি কল super.init()করি তবে আমাকে বলা হবে যে আমি অবশ্যই একটি মনোনীত আরম্ভকারী ব্যবহার করব। আমার সেখানে কী ব্যবহার করা উচিত? ফ্রেম সংস্করণ? কোডার সংস্করণ? উভয়? কেন?

উত্তর:


207

init(frame:)সংস্করণে ডিফল্ট সূচনাকারী হয়। আপনার ইভেন্ট ভেরিয়েবলগুলি শুরু করার পরে আপনাকে অবশ্যই এটি কল করতে হবে। যদি এই ভিউটি কোনও নিব থেকে পুনর্গঠন করা হয় তবে আপনার কাস্টম প্রারম্ভকটিকে ডাকা হবে না এবং পরিবর্তে init?(coder:)সংস্করণটি কল করা হবে। যেহেতু সুইফ্টের এখন প্রয়োজনীয় প্রয়োগের প্রয়োজন init?(coder:), আমি নীচের উদাহরণটি আপডেট করেছি এবং letভেরিয়েবলের ঘোষণাগুলি varএবং al চ্ছিকভাবে পরিবর্তন করেছি । এই ক্ষেত্রে, আপনি এগুলি awakeFromNib()কিছু পরে বা পরে শুরু করতে পারেন।

class TestView : UIView {
    var s: String?
    var i: Int?
    init(s: String, i: Int) {
        self.s = s
        self.i = i
        super.init(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
    }

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

5
তারপরে সেগুলি তৈরি করুন var। তবে সুইফ্টের ডিফল্ট সেরা অনুশীলনটি ভেরিয়েবলগুলি ঘোষণার letকারণ না থাকলে তা ঘোষণা করা var। উপরের আমার কোড উদাহরণে তেমন কোনও কারণ নেই let
ওল্ফ ম্যাকনলি

2
এই কোডটি সংকলন করে না। আপনাকে প্রয়োজনীয় ইনিশিয়ালাইজারটি বাস্তবায়ন করতে হবে init(coder:)
দশক চাঁদ

3
কয়েক বছর আগে এই সংকলিত কিভাবে আকর্ষণীয়। আজকাল এটি আরআইডি (কোডার :) এর অধীনে অভিযোগ করেছে যে "সম্পত্তি স্ব। সুপারসাইটিট কল সূচনা হয়নি"
মাফিয়সো

সুইফট ৩.১ এর স্থির উদাহরণ। কোনও খেলার মাঠের UIKit আমদানি করে সংকলন করে।
ওল্ফ ম্যাকনলি

1
@ লাইটনিট আমি তৈরি করেছি sএবং iএখানে জিনিসগুলি সহজ রাখতে ptionচ্ছিক । যদি তারা alচ্ছিক না হয় তবে তাদের প্রয়োজনীয় আরম্ভকারীতে প্রাথমিককরণও করা উচিত। তাদের alচ্ছিক করা মানে nilযখন super.init()ডাকা হয় তখন তারা হয়ে যায়। যদি তারা alচ্ছিক না হয় তবে তাদের সুপারিনাইট () কল করার আগে অবশ্যই তাদের নিয়োগ করা দরকার।
ওল্ফ ম্যাকনলি

32

আমি মনোনীত এবং প্রয়োজনীয় জন্য একটি সাধারণ init তৈরি করি। সুবিধার জন্য আমি init(frame:)শূন্যের ফ্রেমটি দিয়েছি ।

শূন্য ফ্রেম থাকা কোনও সমস্যা নয় কারণ সাধারণত দর্শনটি একটি ভিউকন্ট্রোলারের দর্শনের অভ্যন্তরে থাকে; আপনার কাস্টম ভিউটি যখন তার তত্ত্বাবধানে কল আসে layoutSubviews()বা এটির পর্যবেক্ষণগুলি বিন্যাস করার জন্য একটি ভাল, নিরাপদ সুযোগ পাবে updateConstraints()। এই দুটি ক্রিয়াকলাপটি ভিউ হায়ারার্কি জুড়ে সিস্টেমকে পুনরাবৃত্তভাবে ডেকে আনে। আপনি হয় updateContstraints()বা ব্যবহার করতে পারেন layoutSubviews()updateContstraints()প্রথমে বলা হয়, তারপর layoutSubviews()। ইন updateConstraints()নিশ্চিত করুন সুপার কল গত । ইন layoutSubviews(), প্রথমে সুপার কল করুন ।

আমি যা করি তা এখানে:

@IBDesignable
class MyView: UIView {

      convenience init(args: Whatever) {
          self.init(frame: CGRect.zero)
          //assign custom vars
      }

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

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

      override func prepareForInterfaceBuilder() {
           super.prepareForInterfaceBuilder()
           commonInit()
      }

      private func commonInit() {
           //custom initialization
      }

      override func updateConstraints() {
           //set subview constraints here
           super.updateConstraints()
      }

      override func layoutSubviews() {
           super.layoutSubviews()
           //manually set subview frames here
      }

}

1
এটা কাজ করে না উচিত: পদ্ধতি কল 'commonInit' এর আগে super.init সূচনা এ 'স্ব' ব্যবহারের স্ব
surfrider

1
সেলফিনটাইট কলের পরে কাস্টম যুক্তিগুলি শুরু করুন। আমার উত্তর আপডেট।
MH175

1
তবে যদি আপনি commonInitপদ্ধতিতে কিছু সম্পত্তি শুরু করতে চান তবে আপনি superএই ক্ষেত্রে এটি পরে রাখতে পারবেন না কারণ superকল করার আগে সমস্ত বৈশিষ্ট্য আপনার আরম্ভ করা উচিত । লোল মনে হচ্ছে মৃত লুপের মতো।
সার্ফ্রাইডার

1
সুইফট সূচনাটি প্রায়শই এভাবে কাজ করে: "দ্বি-পর্যায়ে সূচনা" অনুসন্ধান করুন। আপনি সুস্পষ্টভাবে মোড়কযুক্ত বিকল্পগুলি ব্যবহার করতে পারেন, তবে আমি এটির বিরুদ্ধে প্রস্তাব দিই। আপনার আর্কিটেকচারটি, বিশেষত দর্শনগুলি নিয়ে কাজ করার সময় সমস্ত স্থানীয় বৈশিষ্ট্য আরম্ভ করা উচিত। আমি এখন এই শত শত ভিউতে এই সাধারণআইনিট () পদ্ধতিটি ব্যবহার করেছি। এটি কাজ করে
MH175

17

আমি সুইফটে আইওএস 9 এ এটি কীভাবে করব -

import UIKit

class CustomView : UIView {

    init() {
        super.init(frame: UIScreen.mainScreen().bounds);

        //for debug validation
        self.backgroundColor = UIColor.blueColor();
        print("My Custom Init");

        return;
    }

    required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented"); }
}

উদাহরণ সহ একটি পূর্ণ প্রকল্প এখানে:


2
এটি ভিউয়ের জন্য পুরো প্রদর্শনটি ব্যবহার করবে
রাপ্টোএক্স

1
হাঁ! যদি কোনও আংশিক পর্যবেক্ষণে আগ্রহী হন তবে আমাকে জানান এবং আমি এটিও পোস্ট করব
জে-ডিজল

1
আমার এই উত্তরটি সবচেয়ে ভাল লেগেছে, কারণ মারাত্মক ইররারের অর্থ হ'ল আমাকে প্রয়োজনীয় থিমটিতে কোনও কোড রাখতে হবে না।
কার্টার মেডলিন

1
@ জে-ডিজল, আমি আংশিক দর্শনের সমাধান দেখতে চাই।
এরি ল্যাসেনস্কি

আপনার উত্তর গৃহীত উত্তরের বিপরীতে বলছে না? মানে আপনি পরে কাস্টমাইজেশন করছেন super.init, তবে তিনি বলেছিলেন এটি আগে করা উচিত super.init...
হানি

11

সুইফটে আমি কীভাবে আইওএস-এ একটি সাবভিউ করব -

class CustomSubview : UIView {

    init() {
        super.init(frame: UIScreen.mainScreen().bounds);

        let windowHeight : CGFloat = 150;
        let windowWidth  : CGFloat = 360;

        self.backgroundColor = UIColor.whiteColor();
        self.frame = CGRectMake(0, 0, windowWidth, windowHeight);
        self.center = CGPoint(x: UIScreen.mainScreen().bounds.width/2, y: 375);

        //for debug validation
        self.backgroundColor = UIColor.grayColor();
        print("My Custom Init");

        return;
    }

    required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented"); }
}

4
মারাত্মক ইরর কল () কলটির দুর্দান্ত ব্যবহার। এমনকি প্রাথমিক ব্যবহারকারীর সতর্কবাণীগুলি নিঃশব্দ করার জন্য আমি বিকল্পগুলি ব্যবহার করছিলাম যা এমনকি ব্যবহৃত হচ্ছে না। এই মুহূর্তে এটি বন্ধ! ধন্যবাদ।
মাইক ক্রিচলে 13
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.