কোনও ইউআইভিউ সাবক্লাসের জন্য নিব লোড করার সঠিক উপায়


98

আমি সচেতন যে এই প্রশ্নটি আগে জিজ্ঞাসা করা হয়েছিল তবে উত্তরগুলি বিরোধী এবং আমি বিভ্রান্ত, তাই দয়া করে আমাকে শিখাবেন না।

আমি UIViewআমার অ্যাপ্লিকেশন জুড়ে একটি পুনরায় ব্যবহারযোগ্য সাবক্লাস চাই। আমি একটি নিব ফাইল ব্যবহার করে ইন্টারফেসটি বর্ণনা করতে চাই।

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

যদিও আমি নিব ব্যবহার করে এটি কীভাবে করতে পারি? ফ্রেম সেট না করে ইন্টারফেস বিল্ডারে দেওয়া আকার বজায় রাখা।

আমি এটি এটির মতো করে পরিচালনা করতে পেরেছি তবে আমি নিশ্চিত যে এটি ভুল ((এটিতে কোনও পিকারের সাথে এটি কেবল একটি দৃশ্য):

 - (id)initWithDataSource:(NSDictionary *)dataSource {
        self = [super init];
        if (self){
            self = [[[NSBundle mainBundle] loadNibNamed:[NSString stringWithFormat:@"%@", [self class]] owner:self options:nil] objectAtIndex:0];
            self.pickerViewData = dataSource;
            [self configurePickerView];
        }
        return self;
    }

তবে আমি নিজে থেকে ওভাররাইট করছি, এবং যখন আমি তা ইনস্ট্যান্ট করব:

FSASelectView *selectView = [[FSASelectView alloc] initWithDataSource:selectViewDictionary];
    selectView.delegate = self;

    selectView.frame = CGRectMake(0, self.view.bottom + 50, [FSASelectView width], [FSASelectView height]);

আইবি থেকে তুলে নেওয়ার পরিবর্তে আমাকে ম্যানুয়ালি সেট করতে হবে।

সম্পাদনা: আমি একটি দর্শন নিয়ামকটিতে এই কাস্টম দর্শনটি তৈরি করতে চাই এবং দেখার উপাদানগুলির নিয়ন্ত্রণ করতে অ্যাক্সেস পেতে চাই। আমি নতুন ভিউ কন্ট্রোলার চাই না।

ধন্যবাদ

সম্পাদনা: আমি জানি না এটি সর্বোত্তম অনুশীলন কিনা, আমি নিশ্চিত যে এটি তা নয়, তবে আমি এটি এটি করেছিলাম:

FSASelectView *selectView = [[[NSBundle mainBundle] loadNibNamed:[NSString stringWithFormat:@"%@",[FSASelectView class]] owner:self options:nil] objectAtIndex:0];
    selectView.delegate = self;
    [selectView configurePickerViewWithData:ds];
    selectView.frame = CGRectMake(0, self.view.bottom + 50, selectView.width, selectView.height);
    selectView.alpha = 0.9;
    [self.view addSubview:selectView];
    [UIView animateWithDuration: 0.25 delay: 0 options:UIViewAnimationOptionAllowUserInteraction |UIViewAnimationOptionCurveEaseInOut animations:^{
                            selectView.frame = CGRectMake(0, self.view.bottom - selectView.height, selectView.width, selectView.height);
                            selectView.alpha = 1;
                        } completion:^(BOOL finished) {
                        }];

সঠিক অনুশীলন এখনও চেয়েছিল

ভিউ কন্ট্রোলার এবং এনআইবি নাম সহ আরম্ভ ব্যবহার করে এটি করা উচিত ছিল? কোডটিতে কিছু ইউআইভিউ সূচনা পদ্ধতিতে আমার কি নিব সেট করা উচিত ছিল? বা আমি কি ঠিক আছে?


তবে কোডের প্রথম পংক্তির প্রায় একইরকম নয় যা আপনি মূল প্রশ্নটিতে ব্যবহার করেছেন initWithDataSource? যাইহোক আপনি মালিককে 'নিল' হিসাবে দিলেও এটি কাজ করবে।
রাকেশ

এটি লক্ষণীয় যে আজকাল ৯৯.৯৯৯৯৯% ক্ষেত্রে, এখন কেবল একটি ধারক দৃষ্টিভঙ্গি ব্যবহার করা হবে যা এখন সর্বত্র এবং সর্বদা আইওএস-এ ব্যবহৃত হয়। কীভাবে প্রবন্ধ
ফ্যাটি

পার্শ্ব নোট যে আপনি [এনএসএস স্ট্রিং উইথফর্ম্যাট: @ "% @", [এফএসএলেক্লিটভিউ ক্লাস]] কে এনএসএসটিংফ্রমক্লাসের সাথে [[এফএসএলেকটভিউ ক্লাস]) প্রতিস্থাপন করতে পারবেন
নাওমিমিচিকো

উত্তর:


132
MyViewClass *myViewObject = [[[NSBundle mainBundle] loadNibNamed:@"MyViewClassNib" owner:self options:nil] objectAtIndex:0]

আমি এটি আমার পুনরায় ব্যবহারযোগ্য কাস্টম দর্শনগুলি শুরু করার জন্য ব্যবহার করছি।


মনে রাখবেন যে আপনি সেখানে "ফার্স্টবজেক্ট" ব্যবহার করতে পারেন , এটি কিছুটা পরিষ্কার। "ফার্স্টবজেক্ট" এনএসআরাই এবং এনএস মিউটেবলআরয়ের জন্য একটি সহজ পদ্ধতি।

সারণী শিরোনাম হিসাবে ব্যবহার করার জন্য একটি এক্সিব লোড করার একটি সাধারণ উদাহরণ এখানে's আপনার ফাইলে আপনার ক্লাস.এম

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    return [[NSBundle mainBundle] loadNibNamed:@"TopArea" owner:self options:nil].firstObject;
}

সাধারণত, এর মধ্যে TopArea.xibআপনি ফাইল মালিককে ক্লিক করুন এবং ফাইলের মালিককে আপনার ক্লাসে সেট করবেন । তারপর আসলে YourClass.h মধ্যে আপনি IBOutlet বৈশিষ্ট্য হবে। ইন TopArea.xib, আপনি সেই আউটলেটগুলিতে নিয়ন্ত্রণগুলি টেনে আনতে পারেন।

এটিকে ভুলে যাবেন না TopArea.xib, আপনাকে নিজেই ভিউতে ক্লিক করতে হবে এবং এটি কোনও কোনও আউটলেটে টেনে আনতে হবে, সুতরাং প্রয়োজনে আপনার এটিকে নিয়ন্ত্রণ করতে হবে। (খুব সার্থক টিপ হ'ল আপনি যখন টেবিল সেল সারিগুলির জন্য এটি করছেন, আপনাকে অবশ্যই এটি করতে হবে - আপনাকে নিজের কোডে প্রাসঙ্গিক সম্পত্তির সাথে ভিউটি সংযুক্ত করতে হবে))


কোনও দীক্ষাবিহীন নাম নেই: একটি ইউআইভিউয়ের জন্য পদ্ধতি, এটি কেবল
ইউআইভিউ কনট্রোলারের

এটি একটি ভিউ কন্ট্রোলারের জন্য, আমি একটি ইউআইভিউউ ব্যবহার করতে চাই এবং এমন কন্ট্রোলার রাখতে চাই যা এটির মালিকানা তৈরি করে।
আদম ওয়েট

আমি দুঃখিত, আমি তাড়াতাড়ি ভুল কোডটি অনুলিপি করেছি, আমি উত্তরটি আপডেট করেছি, দয়া করে একবার দেখুন।
প্রেমসুরজ

আমি এই সঠিক চিহ্নিত করতে যাচ্ছি। আমি জানি না এটি সেরা অনুশীলন কিনা তবে এটি কার্যকর হয়।
অ্যাডাম ওয়েট

@ জো ব্লো এই দ্বন্দ্বের জন্য দুঃখিত, তবে কেন এটি করতে হবে: "এটি ভুলে যাবেন না যে টপএরিয়া.অক্সিব, আপনাকে নিজেই ভিউতে ক্লিক করতে হবে এবং এটি কোনও আউটলেটে টানতে হবে, যাতে আপনার নিয়ন্ত্রণ থাকে , যদি প্রয়োজন হয় তাহলে." পরিবর্তে আপনি কেবলমাত্র আমারভিউঅবজেক্টটি ইউআইভিউ হিসাবে অন্তর্নিহিত ভিউ অ্যাক্সেস করতে ব্যবহার করতে পারেন? সম্পত্তি কেন দরকার?
ব্যবহারকারী1686342

39

আপনি যদি নিজের CustomViewএবং এর থেকে xibআলাদা রাখতে চান File's Ownerতবে এই পদক্ষেপগুলি অনুসরণ করুন

  • File's Ownerমাঠটি খালি ছেড়ে দিন ।
  • xibআপনার ফাইলের আসল দৃশ্যে ক্লিক করুন CustomViewএবং এটি (আপনার কাস্টম ভিউ শ্রেণীর নাম) Custom Classহিসাবে সেট করুনCustomView
  • যোগ IBOutletমধ্যে .hআপনার কাস্টম ভিউ ফাইল।
  • ইন .xibআপনার কাস্টম ভিউ ফাইল, দৃশ্য উপর ক্লিক করুন এবং এ যান Connection Inspector। এখানে আপনি আপনার সমস্ত আইবিউটলেটগুলি .hফাইলে সংজ্ঞায়িত করবেন
  • তাদের তাদের নিজ নিজ দৃষ্টিভঙ্গির সাথে সংযুক্ত করুন।

মধ্যে .mআপনার ফাইল CustomViewবর্গ, ওভাররাইড initহিসাবে অনুসরণ পদ্ধতি

-(CustomView *) init{
    CustomView *result = nil;
    NSArray* elements = [[NSBundle mainBundle] loadNibNamed: NSStringFromClass([self class]) owner:self options: nil];
    for (id anObject in elements)
    {
        if ([anObject isKindOfClass:[self class]])
        {
            result = anObject;
            break;
        }
    }
    return result;
}

এখন আপনি যখন নিজেরটি লোড করতে চান CustomView, নীচের কোডটির লাইনটি ব্যবহার করুন [[CustomView alloc] init];


4
আইওএস 9 হিসাবে, এই পৃষ্ঠায় তালিকাভুক্ত একমাত্র সমাধান যা আসলে আমার পক্ষে কাজ করে (অন্যান্য সমাধান ক্র্যাশ হওয়ার কারণ হয়)।
লাইফজয়

কেবলমাত্র নোট করুন যে এই পদ্ধতির কোনও বিদ্যমান XIB থেকে আপনার কাস্টম ভিউ লোড করার সাথে সামঞ্জস্য নয় কারণ এটি কল করে না -init। পরিবর্তে এটি কল করবে initWithFrame:এবং -awakeFromNib। আপনি যদি -initপদ্ধতিতে নিজের ভিউ লোড করতে একই কোডটি লিখেন তবে আপনি একটি অসীম লুপ প্রবেশ করবেন।
পিয়েরে

25

নিম্নলিখিত পদক্ষেপগুলি অনুসরণ করুন

  1. মাইভিউ .h / .m টাইপ নামের একটি শ্রেণি তৈরি করুন UIView
  2. একই নামের একটি xib তৈরি করুন MyView.xib
  3. এখন xib UIViewControllerথেকে ফাইল মালিক শ্রেণি পরিবর্তন করুন NSObject। নীচের চিত্রটি দেখুন এখানে চিত্র বর্ণনা লিখুন
  4. ফাইলের মালিকের দর্শনটিকে আপনার দর্শনে সংযুক্ত করুন। নীচের চিত্রটি দেখুন এখানে চিত্র বর্ণনা লিখুন

  5. আপনার দর্শনের শ্রেণি এতে পরিবর্তন করুন MyView। একই হিসাবে 3।

  6. স্থান নিয়ন্ত্রণ আইবিউটলেটগুলি তৈরি করে।

ভিউ লোড করার কোডটি এখানে:

UIViewController *controller=[[UIViewController alloc] initWithNibName:@"MyView" bundle:nil];
MyView* view=(MyView*)controller.view;
[self.view addSubview:myview];

আশা করি এটা সাহায্য করবে.

স্পষ্টতা :

UIViewControllerআপনার xib এবং ভিউটি লোড করতে ব্যবহৃত হয় যা UIViewControllerআসলে MyViewযা আপনি মাইভিউ এক্সবিতে নির্ধারণ করেছেন ..

ডেমো আমি এখানে একটি ডেমো দখল করেছি


লোকেরা কেন এটিকে ভোট দিচ্ছে, ভুল? আমি এখনও চেষ্টা করি নি, তবে দেখে মনে হচ্ছে এটি আমার যা ইচ্ছা তা করবে না।
আদম ওয়েট

আমি নিচে ভোট দিয়েছি, তবে এটির কারণে আমি আপনার উত্তরটি ভুলভাবে পড়েছি (ভেবেছিলেন আপনি কোনও ইউআইভিউ সাবক্লাসটি ফাইলের মালিক হিসাবে অর্পণ করছেন)। এর জন্যে দুঃখিত.
রাকেশ

4
আপনার xib ফাইলটিতে ফাইলের মালিককে উপেক্ষা করুন। তারপরে আপনি কেবল একটি মাইভিউ * ভিউ = [[ইউআইএনআইবি ইনস্ট্যান্টিয়েট উইথওউনার: নীল বিকল্পসমূহ: শূন্যপদ] শেষঅবজেক্ট] করে একটি ইউআইভিউকন্ট্রোলার তৈরি করা এড়াতে পারবেন;
LightningStryk

4
@ লাইটিংস্ট্রিটক হ্যাঁ অবশ্যই, তবে এটি করার এটি অন্য একটি উপায়।
আইফোনিক

4
হ'ল একটি পুনরায় ব্যবহারযোগ্য ইউআইভিউ উপক্লাস তৈরি করা, সেই উদ্দেশ্যে কোনও ইউআইভিউউকন্ট্রোলার ব্যবহার না করা।
অ্যারিলিজ

11

আমার নিজের প্রশ্নের উত্তর এখানে 2 বা কিছু বছর পরে এখানে কিন্তু ...

এটি একটি প্রোটোকল এক্সটেনশন ব্যবহার করে যাতে আপনি সমস্ত শ্রেণীর জন্য কোনও অতিরিক্ত কোড ছাড়াই এটি করতে পারেন।

/*

Prerequisites
-------------
- In IB set the view's class to the type hook up any IBOutlets
- In IB ensure the file's owner is blank

*/

public protocol CreatedFromNib {
    static func createFromNib() -> Self?
    static func nibName() -> String?
}

extension UIView: CreatedFromNib { }

public extension CreatedFromNib where Self: UIView {

    public static func createFromNib() -> Self? {
        guard let nibName = nibName() else { return nil }
        guard let view = NSBundle.mainBundle().loadNibNamed(nibName, owner: nil, options: nil).last as? Self else { return nil }
        return view
    }

    public static func nibName() -> String? {
        guard let n = NSStringFromClass(Self.self).componentsSeparatedByString(".").last else { return nil }
        return n
    }
}

// Usage:
let myView = MyView().createFromNib()

8

সুইফটে:

উদাহরণস্বরূপ, আপনার কাস্টম শ্রেণীর নাম InfoView

প্রথমে, আপনি ফাইলগুলি তৈরি করেন InfoView.xibএবং এটি InfoView.swiftপছন্দ করেন:

import Foundation
import UIKit

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

তারপরে File's Ownerএটি UIViewControllerপছন্দ করতে সেট করুন :

এখানে চিত্র বর্ণনা লিখুন

আপনার পুনঃনামকরণ Viewকরা InfoView:

এখানে চিত্র বর্ণনা লিখুন

File's Ownerআপনার viewমাঠে রাইট ক্লিক করুন এবং এর সাথে InfoView:

এখানে চিত্র বর্ণনা লিখুন

শ্রেণীর নামটি নিশ্চিত করুন InfoView:

এখানে চিত্র বর্ণনা লিখুন

এবং এর পরে আপনি কোনও সমস্যা ছাড়াই আপনার কাস্টম ক্লাসের বোতামে ক্রিয়াটি যুক্ত করতে পারেন:

এখানে চিত্র বর্ণনা লিখুন

এবং এই কাস্টম শ্রেণীর ব্যবহার আপনার MainViewController:

func someMethod() {
    var v = InfoView.instanceFromNib()
    v.frame = self.view.bounds
    self.view.addSubview(v)
}

2

ওয়েল আপনি হয় একটি ভিউ কন্ট্রোলার ব্যবহার করে xib আরম্ভ করতে পারেন এবং ভিউকন্ট্রোলআরভিউ ব্যবহার করতে পারেন। বা এটি আপনি যেভাবে করেছিলেন তা করুন। কেবলমাত্র UIViewনিয়ন্ত্রক হিসাবে সাবক্লাস তৈরি UIViewকরা একটি খারাপ ধারণা।

যদি আপনার কাস্টম ভিউ থেকে কোনও আউটলেট না থাকে তবে আপনি সরাসরি UIViewControllerএটি শুরু করার জন্য কোনও শ্রেণি ব্যবহার করতে পারেন ।

আপডেট: আপনার ক্ষেত্রে:

UIViewController *genericViewCon = [[UIViewController alloc] initWithNibName:@"CustomView"];
//Assuming you have a reference for the activity indicator in your custom view class
CustomView *myView = (CustomView *)genericViewCon.view;
[parentView addSubview:myView];
//And when necessary
[myView.activityIndicator startAnimating]; //or stop

অন্যথায় আপনাকে একটি কাস্টম UIViewControllerতৈরি করতে হবে (ফাইলের মালিক হিসাবে এটি তৈরি করতে যাতে আউটলেটগুলি সঠিকভাবে ওয়্যার্ড হয়)।

YourCustomController *yCustCon = [[YourCustomController alloc] initWithNibName:@"YourXibName"].

আপনি যেখানেই ভিউ যুক্ত করতে চান আপনি ব্যবহার করতে পারেন।

[parentView addSubview:yCustCon.view];

তবে এক্সবি লোড করার সময় মালিক হিসাবে অন্য ভিউ কন্ট্রোলারটিকে ইতিমধ্যে ব্যবহার করা (ইতিমধ্যে অন্য দর্শনের জন্য ব্যবহৃত হচ্ছে) উত্তীর্ণ হওয়া ভাল ধারণা নয় কারণ নিয়ামকের ভিউ সম্পত্তিটি পরিবর্তিত হবে এবং আপনি যখন আসল দৃশ্যে অ্যাক্সেস করতে চান তখন আপনি পাবেন না এটি একটি রেফারেন্স আছে।

সম্পাদনা: আপনি যদি নিজের নতুন xib ফাইলের মালিকের সাথে একই প্রধান শ্রেণীরূপে সেটআপ করেন UIViewControllerএবং ভিউ সম্পত্তিটি নতুন xib দর্শনে আবদ্ধ করেন তবে আপনি এই সমস্যার মুখোমুখি হবেন ।

অর্থাত্;

  • আপনারমেনভিউকন্ট্রোলার - পরিচালনা - মেনভিউ
  • কাস্টমভিউ - যখন প্রয়োজন হয় তখন xib থেকে লোড করা দরকার।

নীচের কোডটি পরে বিভ্রান্তি সৃষ্টি করবে, আপনি যদি এটি ভিতরে দেখেন তবে ভিউ লোড হয় YourMainViewController। কারণ এটি self.viewথেকে আপনার কাস্টমভিউটি উল্লেখ করা হবে

-(void)viewDidLoad:(){
  UIView *childView= [[[NSBundle mainBundle] loadNibNamed:@"YourXibName" owner:self options:nil] objectAtIndex:0];
}

ঠিক আছে, তাই মূলত, সর্বোত্তম অনুশীলন বলে যে প্রতিটি ইউআইভিউয়ের একটি সম্পর্কিত নিয়ামক থাকা উচিত?
অ্যাডাম ওয়েট

অগত্যা। তবে কোনও পৃথক এক্সবি থেকে কোনও ভিউ লোড করার সময় এটি সমস্যা-মুক্ত উপায় হবে। প্রাক আইওএস 5 অ্যাপল ডক্স বলছে যে একের অধিক দৃশ্যের (xib) এবং তদ্বিপরীত নিয়ন্ত্রণ করতে একটি ভিউ কন্ট্রোলার ব্যবহার করা উচিত নয়।
রাকেশ

Xib আসলে একটি সতর্কতা দর্শনের আকার
অ্যাডাম ওয়েট

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

4
সুতরাং আমি ইন্টারফেসটি প্রোগ্রামারিকভাবে না করে ইন্টারফেস বিল্ডারে আঁকতে পারি। প্রোগ্রামিয়ালি এটি করা কোনও সমস্যা নয়, আমি কেবলমাত্র একটি ইউআইভিউউকে কীভাবে সাবক্লাস করব এবং এটিকে একটি নিব দিতে চাই তা জানতে চাই! এটি কঠিন হতে হবে না।
অ্যাডাম ওয়েট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.