আপনি কীভাবে Xib ফাইলগুলি থেকে কাস্টম UITableViewCells লোড করবেন?


293

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

এখানে আমি ব্যবহার করেছি এমন কিছু কোড রয়েছে:

static NSString *CellIdentifier = @"MyCellIdentifier";

MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil];
    cell = (MyCell *)[nib objectAtIndex:0];
}

এই কোডটি ব্যবহার করতে, MyCell.m / .h তৈরি করুন, এর একটি নতুন উপক্লাস তৈরি করুন এবং আপনার পছন্দসই উপাদানগুলির জন্য UITableViewCellযুক্ত করুন IBOutlets। তারপরে একটি নতুন "খালি XIB" ফাইল তৈরি করুন। আইবিতে Xib ফাইলটি খুলুন, একটি UITableViewCellঅবজেক্ট যুক্ত করুন, "মাইসেলআইডিটিফায়ার" এর শনাক্তকারীকে সেট করুন এবং এর ক্লাসটি মাইসেলে সেট করুন এবং আপনার উপাদানগুলি যুক্ত করুন। অবশেষে IBOutletsউপাদানগুলির সাথে সংযোগ করুন । নোট করুন যে আমরা আইবিতে ফাইলের মালিক সেট করি নি।

অন্যান্য পদ্ধতিগুলি ফাইলের মালিক সেট করার পক্ষে এবং যদি অতিরিক্ত কারখানার শ্রেণীর মাধ্যমে Xib লোড না করা হয় তবে মেমরি ফাঁস সম্পর্কে সতর্ক করে। আমি উপরের সরঞ্জাম / লিকগুলির অধীনে পরীক্ষা করেছি এবং কোনও মেমরি ফাঁস দেখিনি।

তাহলে Xibs থেকে ঘর লোড করার আধ্যাত্মিক উপায় কী? আমরা কি ফাইলের মালিক সেট করব? আমাদের কি কারখানা দরকার? যদি তা হয় তবে কারখানার কোডটি কেমন? যদি একাধিক সমাধান থাকে তবে আসুন তাদের প্রত্যেকের উপকারিতা এবং মতামত পরিষ্কার করুন ...


2
কেউ আসলে প্রশ্নটি জিজ্ঞাসা করতে বিষয়টিকে সম্পাদনা করতে পারে, যেমন "আপনি কীভাবে Xib ফাইলগুলি থেকে কাস্টম UITableViewCells লোড করবেন?" (স্ট্যাকওভারফ্লোতে এটি কেবল সম্ভব না হলে উপেক্ষা করুন))
স্টিভেন ফিশার

1
আইওএস 5 এবং এর বাইরে, এটি সমাধান: স্ট্যাকওভারফ্লো / প্রশ্নগুলি / 15591364/… , যা জিউসেপের সমাধান হিসাবে একই।
ম্যাট বেকার

দ্রুত নোট, সহজতর (2013 পারিপার্শ্বিক) উত্তর এখানে stackoverflow.com/questions/15378788/... jamihash
Fattie

উত্তর:


288

এখানে আইবি ইঞ্জিনিয়ার দ্বারা মূল লেখককে দুটি পদ্ধতির প্রস্তাব দেওয়া হয়েছিল

আরও তথ্যের জন্য আসল পোস্ট দেখুন। আমি পদ্ধতিটি 2 পছন্দ করি কারণ এটি সহজ বলে মনে হয়।

পদ্ধতি # 1:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BDCustomCell"];
    if (cell == nil) {
        // Create a temporary UIViewController to instantiate the custom cell.
        UIViewController *temporaryController = [[UIViewController alloc] initWithNibName:@"BDCustomCell" bundle:nil];
        // Grab a pointer to the custom cell.
        cell = (BDCustomCell *)temporaryController.view;
        [[cell retain] autorelease];
        // Release the temporary UIViewController.
        [temporaryController release];
    }

    return cell;
}

পদ্ধতি # 2:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BDCustomCell"];
    if (cell == nil) {
        // Load the top-level objects from the custom cell XIB.
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"BDCustomCell" owner:self options:nil];
        // Grab a pointer to the first object (presumably the custom cell, as that's all the XIB should contain).
        cell = [topLevelObjects objectAtIndex:0];
    }

    return cell;
}

আপডেট (2014): পদ্ধতি # 2 এখনও বৈধ তবে এটির জন্য আর কোনও ডকুমেন্টেশন নেই। এটি সরকারী দস্তাবেজে থাকত তবে এখন স্টোরিবোর্ডের পক্ষে সরানো হয়েছে।

আমি গিথুবে একটি কার্যকারী উদাহরণ পোস্ট করেছি:
https://github.com/bentford/NibTableCellExample

সুইফট ৪.২ এর জন্য সম্পাদনা করুন

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
    self.tblContacts.register(UINib(nibName: CellNames.ContactsCell, bundle: nil), forCellReuseIdentifier: MyIdentifier)
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: MyIdentifier, for: indexPath) as! ContactsCell

    return cell
}

1
পদ্ধতি 1 এর জন্য, আপনার "সেল = (বিডিসিস্টমসেল *) এর মতো কিছু করা উচিত নয় [[অস্থায়ীকন্ট্রোলার ভিউ ধরে রাখুন] স্বতঃপরে]]" সুতরাং অস্থায়ী নিয়ামক প্রকাশিত হলে সেলটি মুক্তি পায় না?
টড কানিংহাম

হুঁ। # 2 সম্পর্কে যে ডকুমেন্টেশনগুলি কথা বলছে তা এখনও আপনাকে একটি XIB ফাইলে সেলটির মালিককে একটি পরিচিত নিয়ামক শ্রেণিতে সেট করতে বলে। সম্ভবত লোড করার সময় আপনি মালিককে সেট করেন তা বিবেচ্য নয়।
অস্কার

@ অস্কারগলডম XIB ফাইলে সেই সেলটির মালিক একটি শ্রেণি (যেমন মালিকের ধরণ))
বেন্টফোর্ড 0

2
@ কুলডোকম্যান অপশন # 2 এখনও কাজ করে। সমস্যাটি খুব সম্ভবত নিব সাথে দেখা দেয়। এখানে একটি উদাহরণ রয়েছে: github.com/bentford/NibTableCellExample
বেন্টফোর্ড

2
এই সুপার ওল্ড কোডটি এত বেশি র‌্যাঙ্ক কেন? স্ট্যাকওভারফ্লো কিছু করুন: /
নিকো এস

304

সঠিক সমাধানটি হ'ল:

- (void)viewDidLoad
{
    [super viewDidLoad];
    UINib *nib = [UINib nibWithNibName:@"ItemCell" bundle:nil];
    [[self tableView] registerNib:nib forCellReuseIdentifier:@"ItemCell"];
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Create an instance of ItemCell
    PointsItemCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ItemCell"];

    return cell;
}

আইওএস 5 অ্যাপসটি কি ভেঙে যাচ্ছে? আমি সত্যই ইউএনআইবি কখনও দেখিনি
অ্যাডাম

@ অ্যাডামওয়েট নিবন্ধভুক্ত এনআইবি ফাইলগুলি আইওএস 5 এবং তারপরের জন্য কাজ করে, সুতরাং এটি আইওএস 5 অ্যাপ্লিকেশন ভঙ্গ করছে না। এবং ইউআইএনআইবি এমনকি আইওএস ৪
মেকি

: একটি ভাল উদাহরণস্বরূপ, Git রেপো শীর্ষ উত্তর এখানে উল্লেখ পরীক্ষা stackoverflow.com/questions/18746929/...
netigger

39

নিবন্ধন

আইওএস 7 এর পরে, এই প্রক্রিয়াটি নীচে সরল করা হয়েছে ( স্যুইফ্ট 3.0 ):

// For registering nib files
tableView.register(UINib(nibName: "MyCell", bundle: Bundle.main), forCellReuseIdentifier: "cell")

// For registering classes
tableView.register(MyCellClass.self, forCellReuseIdentifier: "cell")

( দ্রষ্টব্য ) প্রোটোটাইপ কোষ হিসাবে .xibবা .stroyboardফাইলগুলিতে ঘর তৈরি করে এটিও অর্জনযোগ্য । আপনার যদি তাদের সাথে কোনও শ্রেণি সংযুক্ত করার প্রয়োজন হয় তবে আপনি সেল প্রোটোটাইপটি নির্বাচন করতে পারেন এবং সংশ্লিষ্ট শ্রেণিটি (অবশ্যই অবশ্যই এর বংশধর হতে হবে UITableViewCell) যোগ করতে পারেন।

dequeue

এবং পরবর্তীতে, ( দ্রুত 3.0.০ ) ব্যবহার করে শনাক্ত করা হয়েছে :

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    let cell : UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

    cell.textLabel?.text = "Hello"

    return cell
}

পার্থক্যটি হ'ল এই নতুন পদ্ধতিটি কেবলমাত্র কোষকেই প্রাপ্য নয়, অ-অস্তিত্বশীল হওয়ার অর্থ এটিও তৈরি করে (যার অর্থ আপনার শেনানিগান করতে হবে না if (cell == nil)), এবং ঘরটি উপরের উদাহরণের মতোই ব্যবহার করতে প্রস্তুত।

( সতর্কতা ) tableView.dequeueReusableCell(withIdentifier:for:)এর নতুন আচরণ রয়েছে, যদি আপনি অন্যটিকে কল করেন (ছাড়াই indexPath:) আপনি পুরানো আচরণটি পান, যাতে আপনাকে nilএটি পরীক্ষা করে দেখার প্রয়োজন হয় এবং এটির পুনরুদ্ধারের UITableViewCell?মানটি লক্ষ্য করুন ।

if let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? MyCellClass
{
    // Cell be casted properly
    cell.myCustomProperty = true
}
else
{
    // Wrong type? Wrong identifier?
}

এবং অবশ্যই, ঘরের সাথে সম্পর্কিত শ্রেণীর ধরণটি আপনি UITableViewCellসাবক্লাসের জন্য .xib ফাইলে সংজ্ঞায়িত করেছেন বা বিকল্পভাবে, অন্য রেজিস্টার পদ্ধতিটি ব্যবহার করে।

কনফিগারেশন

আদর্শভাবে, আপনার ঘরগুলি ইতিমধ্যে উপস্থিতি এবং বিষয়বস্তু অবস্থানের শর্তাবলী (যেমন লেবেল এবং চিত্রের মতামত) এর দ্বারা কনফিগার করা হয়েছে আপনি সেগুলি নিবন্ধ করার সময় এবং cellForRowAtIndexPathপদ্ধতিতে আপনি কেবল সেগুলি পূরণ করেন।

সব একসাথে

class MyCell : UITableViewCell
{
    // Can be either created manually, or loaded from a nib with prototypes
    @IBOutlet weak var labelSomething : UILabel? = nil
}

class MasterViewController: UITableViewController 
{
    var data = ["Hello", "World", "Kinda", "Cliche", "Though"]

    // Register
    override func viewDidLoad()
    {
        super.viewDidLoad()

        tableView.register(MyCell.self, forCellReuseIdentifier: "mycell")
        // or the nib alternative
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return data.count
    }

    // Dequeue
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
    {
        let cell = tableView.dequeueReusableCell(withIdentifier: "mycell", for: indexPath) as! MyCell

        cell.labelSomething?.text = data[indexPath.row]

        return cell
    }
}

এবং অবশ্যই, এটি একই নামগুলির সাথে ওবিজেসি-তে উপলব্ধ।


এখানে আপত্তিজনক সংস্করণটি দেওয়া হয়েছে:[self.tableView registerNib:[UINib nibWithNibName:@"BlaBlaTableViewCell" bundle:nil] forCellReuseIdentifier:kCellIdentifier];
জেব

33

শন ক্র্যাভারের উত্তর নিয়েছে এবং এটি কিছুটা সাফ করেছে।

BBCell.h:

#import <UIKit/UIKit.h>

@interface BBCell : UITableViewCell {
}

+ (BBCell *)cellFromNibNamed:(NSString *)nibName;

@end

BBCell.m:

#import "BBCell.h"

@implementation BBCell

+ (BBCell *)cellFromNibNamed:(NSString *)nibName {
    NSArray *nibContents = [[NSBundle mainBundle] loadNibNamed:nibName owner:self options:NULL];
    NSEnumerator *nibEnumerator = [nibContents objectEnumerator];
    BBCell *customCell = nil;
    NSObject* nibItem = nil;
    while ((nibItem = [nibEnumerator nextObject]) != nil) {
        if ([nibItem isKindOfClass:[BBCell class]]) {
            customCell = (BBCell *)nibItem;
            break; // we have a winner
        }
    }
    return customCell;
}

@end

আমি আমার সমস্ত ইউআইটিএবলভিউসেল বিবিসিএলের সাবক্লাসগুলি তৈরি করি এবং তারপরে মানটি প্রতিস্থাপন করি

cell = [[[BBDetailCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"BBDetailCell"] autorelease];

সঙ্গে:

cell = (BBDetailCell *)[BBDetailCell cellFromNibNamed:@"BBDetailCell"];

16

আমি বেন্টফোর্ডের পদ্ধতিটি # 2 ব্যবহার করেছি :

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BDCustomCell"];
    if (cell == nil) {
        // Load the top-level objects from the custom cell XIB.
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"BDCustomCell" owner:self options:nil];
        // Grab a pointer to the first object (presumably the custom cell, as that's all the XIB should contain).
        cell = [topLevelObjects objectAtIndex:0];
    }

    return cell;
}

এটি কাজ করে তবে আপনার কাস্টম ইউআইটিএবলভিউসেল .xib ফাইলটিতে ফাইলের মালিকের সাথে সংযোগগুলি দেখুন ।

owner:selfআপনার loadNibNamedবিবৃতিটি পাস করার মাধ্যমে আপনি UITableViewControllerনিজের ফাইলটির মালিক হিসাবে সেট করেছেন UITableViewCell

আপনি যদি ক্রিয়া এবং আউটলেটগুলি সেট আপ করতে আইবিতে শিরোলেখ ফাইলটিতে টানুন এবং ছেড়ে দিন, এটি ডিফল্টরূপে সেগুলি ফাইলের মালিক হিসাবে সেট আপ করবে।

ইন loadNibNamed:owner:options, অ্যাপলের কোড আপনার উপর সম্পত্তি সেট করার চেষ্টা করবে UITableViewController, কারণ এটি মালিক that's তবে সেখানে আপনার সেই বৈশিষ্ট্যগুলি সংজ্ঞায়িত করা হয়নি, সুতরাং আপনি কী মান কোডিং-অনুবর্তী হওয়ার বিষয়ে ত্রুটি পাবেন :

*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason:     '[<MyUITableViewController 0x6a383b0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key myLabel.'

যদি এর পরিবর্তে কোনও ইভেন্ট ট্রিগার হয়ে যায়, আপনি একটি এনএসআইএনওডিয়ালআরগমেন্ট এক্সেক্সেশন পাবেন:

-[MyUITableViewController switchValueDidChange:]: unrecognized selector sent to instance 0x8e9acd0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MyUITableViewController switchValueDidChange:]: unrecognized selector sent to instance 0x8e9acd0'
*** First throw call stack:
(0x1903052 0x15eed0a 0x1904ced 0x1869f00 0x1869ce2 0x1904ec9 0x5885c2 0x58855a 0x62db76 0x62e03f 0x77fa6c 0x24e86d 0x18d7966 0x18d7407 0x183a7c0 0x1839db4 0x1839ccb 0x1f8b879 0x1f8b93e 0x585a9b 0xb904d 0x2c75)
terminate called throwing an exceptionCurrent language:  auto; currently objective-c

UITableViewCellফাইলের মালিকের পরিবর্তে আপনার ইন্টারফেস বিল্ডার সংযোগগুলি নির্দেশ করা সহজ কাজ ar

  1. সংযোগগুলির তালিকাটি টানতে ফাইলের মালিককে ডান ক্লিক করুন
  2. কমান্ড-শিফট -4 দিয়ে স্ক্রিন ক্যাপচার নিন (ধরার জন্য অঞ্চলটি নির্বাচন করতে টানুন)
  3. এক্স ফাইলের মালিক থেকে সংযোগগুলি আউট
  4. অবজেক্ট হায়ারার্কিতে ইউআইটিএবলসেলটিতে ডান ক্লিক করুন এবং সংযোগগুলি পুনরায় যুক্ত করুন।

আপনার উল্লিখিত সমস্যাটি আমার ছিল, তবে কীভাবে ফাইলের মালিকের পরিবর্তে ইউআইটিবেলভিউসেল সংযোগগুলি যুক্ত করবেন? আমি আপনার পদক্ষেপগুলি বুঝতে পারি না, উদাহরণস্বরূপ কেন স্ক্রিনশট নেওয়া দরকার? এবং যখন আমি আউটলেটটির পাশের অ্যাড বোতামটি ক্লিক করি তখন কিছুই ঘটে না
xu huanze

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

অনেক ধন্যবাদ, আমার কাছে ছিল "সমস্যাটি কী এর মূল কোডিং-কমপ্লায়েন্ট নয়" এই সমস্যাটি এবং আপনার সহায়তায় সমাধান করেছেন। আমি অন্যকে বলতে চাই, আপনার কাস্টম সেল শ্রেণীরূপে ব্যবহার করা আপনার ইউআইটিএবলভিউসেল এর একটি শ্রেণিকেও আপনার ক্লাসে পরিবর্তন করা উচিত।
ডেনিস কুতলুবায়েভ

14

আমি যেহেতু এই উত্তরগুলির কোনও পছন্দ করি না সেহেতু আমি পোস্ট করার সিদ্ধান্ত নিয়েছি - জিনিসগুলি সর্বদা সহজ হতে পারে এবং এটি আমার সর্বাধিক সংক্ষিপ্ত উপায়।

আপনার ইন্টারফেস নির্মাতাকে আপনার পছন্দ মতো এটি তৈরি করুন

  • ফাইলের মালিককে ক্লাস এনএসবজেক্টে সেট করুন
  • একটি ইউআইটিএবলভিউসেল যুক্ত করুন এবং এটির ক্লাসটি মাইটিবেলভিউসেলক্ল্যাশকে সেট করুন - যদি আপনার আইবি ক্র্যাশ হয় (এই লেখার সাথে সাথে এক্সকোড> 4 এ ঘটে), কেবল আপনার যদি এখনও এটি বিছানায় থাকে তবে এক্সকোড 4 এ ইন্টারফেসটি করার একটি ইউআইভিউ ব্যবহার করুন
  • এই ঘরের অভ্যন্তরে আপনার মতামতগুলি লেআউট করুন এবং আপনার IBOutlet সংযোগগুলি আপনার .h বা .m তে আপনার @ অভ্যন্তরীণ পৃষ্ঠায় সংযুক্ত করুন (। মি আমার পছন্দ)

২. আপনার ইউআইভিউকন্ট্রোলার বা ইউআইটিএবল ভিউ কনট্রোলার সাবক্লাসে

@implementation ViewController

static NSString *cellIdentifier = @"MyCellIdentier";

- (void) viewDidLoad {

    ...
    [self.tableView registerNib:[UINib nibWithNibName:@"MyTableViewCellSubclass" bundle:nil] forCellReuseIdentifier:cellIdentifier];
}

- (UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    MyTableViewCellSubclass *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    ...

    return cell;
}

৩.আপনার মাইটেবলভিউসেলসব্লাক্লাসে

- (id) initWithCoder:(NSCoder *)aDecoder {
    if (self = [super initWithCoder:aDecoder]) {
        ...
    }

    return self;
}

9

যদি আপনি ঘর তৈরি করতে ইন্টারফেস বিল্ডার ব্যবহার করে থাকেন তবে আপনি পরিদর্শকটিতে পরিচয়দাতা সেট করেছেন তা পরীক্ষা করুন। তারপরে DequeueReusableCellWithIdentifier কল করার সময় তা পরীক্ষা করে দেখুন।

আমি দুর্ঘটনাক্রমে একটি টেবিল-ভারী প্রকল্পে কিছু শনাক্তকারী সেট করতে ভুলে গিয়েছিলাম, এবং পারফরম্যান্সের পরিবর্তনটি ছিল রাত্রে দিনের মতো।


8

এক্সআইবিএস থেকে ইউআইটিএবলভিউকেলগুলি লোড করা প্রচুর কোড সাশ্রয় করে তবে সাধারণত ভয়াবহ স্ক্রোলিং গতির ফলাফল হয় (আসলে এটি এক্সআইবি নয় তবে ইউআইভিউউগুলির অত্যধিক ব্যবহার যা এটি সৃষ্টি করে)।

আমি আপনাকে এইটি একবার দেখার পরামর্শ দিচ্ছি: লিঙ্ক রেফারেন্স


6

একাদশটি থেকে কাস্টম সেল তৈরি করার জন্য আমি যে শ্রেণীর পদ্ধতিটি ব্যবহার করছি তা এখানে:

+ (CustomCell*) createNewCustomCellFromNib {

    NSArray* nibContents = [[NSBundle mainBundle]
                            loadNibNamed:@"CustomCell" owner:self options:NULL];

    NSEnumerator *nibEnumerator = [nibContents objectEnumerator];
    CustomCell *customCell= nil;
    NSObject* nibItem = nil;

    while ( (nibItem = [nibEnumerator nextObject]) != nil) {

        if ( [nibItem isKindOfClass: [CustomCell class]]) {
            customCell = (CustomCell*) nibItem;

            if ([customCell.reuseIdentifier isEqualToString: @"CustomCell"]) {
                break; // we have a winner
            }
            else
                fuelEntryCell = nil;
        }
    }
    return customCell;
}

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

[[UITableViewCell] alloc] initWithFrame:]

এটি যথেষ্ট পরিমাণে দ্রুত এবং আমার দুটি শিপিং অ্যাপ্লিকেশনটিতে ব্যবহৃত হচ্ছে। এটি কল করার চেয়ে বেশি নির্ভরযোগ্য [nib objectAtIndex:0]এবং আমার মনে কমপক্ষে স্টিফেন বুর্লটের উদাহরণের চেয়ে বেশি নির্ভরযোগ্য কারণ আপনি সঠিক ধরণের XIB এর বাইরে কেবলমাত্র একটি দৃশ্য দখল করার গ্যারান্টিযুক্ত।


5

সঠিক সমাধান এটি

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.tableView registerNib:[UINib nibWithNibName:@"CustomCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"CustomCell"];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell  *cell = [tableView dequeueReusableCellWithIdentifier:@"CustomCell"];
    return cell; 
    }

4

এনআইবি পুনরায় লোড করা ব্যয়বহুল। এটি একবার লোড করা ভাল, তারপরে আপনার যখন কোনও ঘরের প্রয়োজন হবে তখন অবজেক্টগুলি ইনস্ট্যান্ট করুন। নোট করুন যে আপনি এই পদ্ধতিটি ব্যবহার করে নিবিব এমনকি একাধিক কোষগুলিতে ইউআইআইমেজভিউস ইত্যাদি যুক্ত করতে পারেন (অ্যাপলের "রেজিস্ট্রেশনআইআইবি" আইওএস 5 কেবলমাত্র একটি শীর্ষ স্তরের অবজেক্টের অনুমতি দেয় - বাগ 10580062 "আইওএস 5 টেবিলভিউ নিবন্ধনিব: অতিরিক্ত মাত্রায় নিষিদ্ধ"

সুতরাং আমার কোডটি নীচে রয়েছে - আপনি একবার এনআইবিতে পড়েছেন (প্রথমদিকে যেমনটি আমি করেছি বা ভিউডিডোডে - যাই হোক না কেন) তারপরে, আপনি নিবকে অবজেক্টগুলিতে ইনস্ট্যান্ট করুন তারপরে আপনার প্রয়োজনীয় একটিটি চয়ন করুন n এটি নিব লোড করার চেয়ে অনেক বেশি কার্যকর বারবার.

static UINib *cellNib;

+ (void)initialize
{
    if(self == [ImageManager class]) {
        cellNib = [UINib nibWithNibName:@"ImageManagerCell" bundle:nil];
        assert(cellNib);
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellID = @"TheCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
    if(cell == nil) {
        NSArray *topLevelItems = [cellNib instantiateWithOwner:nil options:nil];
        NSUInteger idx = [topLevelItems indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop)
                            {
                                UITableViewCell *cell = (UITableViewCell *)obj;
                                return [cell isKindOfClass:[UITableViewCell class]] && [cell.reuseIdentifier isEqualToString:cellID];
                            } ];
        assert(idx != NSNotFound);
        cell = [topLevelItems objectAtIndex:idx];
    }
    cell.textLabel.text = [NSString stringWithFormat:@"Howdie %d", indexPath.row];

    return cell;
}

4

এটি পরীক্ষা করুন - http://eppz.eu/blog/custom-uitableview-cell/ - একটি ক্ষুদ্র শ্রেণীর ব্যবহার করে সুবিধাজনক সুবিধাজনক উপায় যা নিয়ামক প্রয়োগের এক লাইনে শেষ হয়:

-(UITableViewCell*)tableView:(UITableView*) tableView cellForRowAtIndexPath:(NSIndexPath*) indexPath
{
    return [TCItemCell cellForTableView:tableView
                          atIndexPath:indexPath
                      withModelSource:self];
}

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


3

এটি করার সঠিক উপায়টি হল একটি ইউআইটিএবলভিউসেল সাবক্লাস বাস্তবায়ন, শিরোনাম এবং এক্সআইবি। এক্সআইবিতে কোনও দর্শন সরিয়ে ফেলুন এবং কেবল একটি টেবিল ঘর যুক্ত করুন। ক্লাসটি ইউআইটিএবল ভিউসেল সাবক্লাসের নাম হিসাবে সেট করুন। ফাইলের মালিকের জন্য, এটি ইউআইটিএবল ভিউকন্ট্রোলার সাবক্লাস শ্রেণীর নাম করুন। টেবিলভিউ সেল আউটলেটটি ব্যবহার করে সেলে ফাইলের মালিককে সংযুক্ত করুন।

শিরোলেখ ফাইলটিতে:

UITableViewCell *_tableViewCell;
@property (assign) IBOutlet UITableViewCell *tableViewCell;

বাস্তবায়ন ফাইলে:

@synthesize tableViewCell = _tableViewCell;

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *kCellIdentifier = @"reusableCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
    if (cell == nil) {
        [[NSBundle mainBundle] loadNibNamed:kCellIdentifier owner:self options:nil];
        cell = _tableViewCell;
        self.tableViewCell = nil;
    }

    return cell;
}

3

আমি এর জন্য যা করছি তা IBOutlet UITableViewCell *cellআপনার নিয়ামক শ্রেণিতে একটি ঘোষণা করে declare তারপরে NSBundle loadNibNamedক্লাস পদ্ধতিটি অনুরোধ করুন, যা খাদ্য সরবরাহ করবেUITableViewCell উপরের ঘোষিত কক্ষে ।

Xib এর জন্য আমি একটি খালি xib তৈরি করব এবং আইবিতে UITableViewCellএটি যুক্ত করব যেখানে এটি প্রয়োজন হিসাবে সেটআপ করা যেতে পারে। এই দৃশ্যটি তখন IBOutletনিয়ামক শ্রেণীর কক্ষের সাথে সংযুক্ত থাকে ।

- (UITableViewCell *)tableView:(UITableView *)table
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"%@ loading RTEditableCell.xib", [self description] );

    static NSString *MyIdentifier = @"editableCellIdentifier";
    cell = [table dequeueReusableCellWithIdentifier:MyIdentifier];

    if(cell == nil) {
        [[NSBundle mainBundle] loadNibNamed:@"RTEditableCell"
                                      owner:self
                                    options:nil];
    }

    return cell;
}

এনএসবান্ডেল সংযোজনগুলি লোডনাবনেড (এডিসি লগইন)

cocoawithlove.com নিবন্ধটি থেকে ধারণাটি উত্সাহ পেয়েছি (ফোন নম্বরগুলির নমুনা অ্যাপ্লিকেশনটি পান)


3
  1. AbcViewCellথেকে আপনার নিজস্ব কাস্টমাইজড বর্গ সাবক্লাস তৈরি করুন UITableViewCell(আপনার শ্রেণীর ফাইলের নাম এবং নিব ফাইলের নাম একই রয়েছে তা নিশ্চিত করুন)

  2. এই এক্সটেনশন ক্লাস পদ্ধতিটি তৈরি করুন।

    extension UITableViewCell {
        class func fromNib<T : UITableViewCell>() -> T {
            return Bundle.main.loadNibNamed(String(describing: T.self), owner: nil, options: nil)?[0] as! T
        }
    }
  3. এটা ব্যবহার করো.

    let cell: AbcViewCell = UITableViewCell.fromNib()


2

প্রথমে আপনার কাস্টম সেল ফাইলটি আমদানি করুন #import "CustomCell.h"এবং তারপরে নীচে উল্লিখিত হিসাবে ডেলিগেট পদ্ধতিটি পরিবর্তন করুন:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *simpleTableIdentifier = @"CustomCell";

CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
    cell = [nib objectAtIndex:0];

    [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
}         

     return cell;
}

2

ইন সুইফট 4.2 এবং Xcode 10

আমার কাছে তিনটি এক্সআইবি সেল ফাইল রয়েছে

ViewDidLoad এ আপনার XIB ফাইলগুলি এইভাবে নিবন্ধ করুন ...

এটি প্রথম পন্থা

tableView.register(UINib.init(nibName: "XIBCell", bundle: nil), forCellReuseIdentifier: "cell1")
tableView.register(UINib.init(nibName: "XIBCell2", bundle: nil), forCellReuseIdentifier: "cell2")
//tableView.register(UINib.init(nibName: "XIBCell3", bundle: nil), forCellReuseIdentifier: "cell3")

দ্বিতীয় পন্থা সরাসরি সেলফোরআউএড ইনডেক্সপথে XIB ফাইলগুলি নিবন্ধন করুন :

এটি আমার টেবিলভিউ প্রতিনিধি ফাংশন

//MARK: - Tableview delegates
override func numberOfSections(in tableView: UITableView) -> Int {

    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return 6
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    //This is first approach
    if indexPath.row == 0 {//Load first XIB cell
        let placeCell = tableView.dequeueReusableCell(withIdentifier: "cell1") as! XIBCell
        return placeCell
    //Second approach
    } else if indexPath.row == 5 {//Load XIB cell3
        var cell = tableView.dequeueReusableCell(withIdentifier:"cell3") as? XIBCell3
        if cell == nil{
            let arrNib:Array = Bundle.main.loadNibNamed("XIBCell3",owner: self, options: nil)!
            cell = arrNib.first as? XIBCell3
        }

        //ADD action to XIB cell button
        cell?.btn.tag = indexPath.row//Add tag to button
        cell?.btn.addTarget(self, action: #selector(self.bookbtn1(_:)), for: .touchUpInside);//selector

        return cell!
    //This is first approach
    } else {//Load XIB cell2
        let placeCell = tableView.dequeueReusableCell(withIdentifier: "cell2") as! XIBCell2

        return placeCell
    }

}

1

এটির জন্য আমার পদ্ধতিটি এখানে: এক্সআইবি ফাইলগুলি থেকে কাস্টম ইউআইটিএবলভিউকেলগুলি লোড হচ্ছে ... তবুও অন্য একটি পদ্ধতি

আপনার কোড থেকে কনফিগার করতে হবে এমন প্রতিটি কাস্টম সাবভিউয়ের জন্য UITableViewCellএকটি IBOutlet UIView *contentসম্পত্তি এবং সম্পত্তি সহ একটি স্যাম্পেলসেল উপক্লাস তৈরির ধারণা । তারপরে একটি স্যাম্পেলসেল.এক্সিব ফাইল তৈরি করতে। এই নিব ফাইলটিতে, ফাইলের মালিককে নমুনা সেলিতে পরিবর্তন করুন। UIViewআপনার প্রয়োজন মাপসই আকারের একটি সামগ্রী যুক্ত করুন । আপনি চান সমস্ত সাবভিউ (লেবেল, চিত্র দেখুন, বোতাম, ইত্যাদি) যুক্ত এবং কনফিগার করুন। পরিশেষে, সামগ্রী মালিক এবং সাবভিউগুলি ফাইলের মালিকের সাথে লিঙ্ক করুন।


1

এখানে কক্ষগুলি নিবন্ধকরণের জন্য একটি সর্বজনীন পদ্ধতির UITableView:

protocol Reusable {
    static var reuseID: String { get }
}

extension Reusable {
    static var reuseID: String {
        return String(describing: self)
    }
}

extension UITableViewCell: Reusable { }

extension UITableView {

func register<T: UITableViewCell>(cellClass: T.Type = T.self) {
    let bundle = Bundle(for: cellClass.self)
    if bundle.path(forResource: cellClass.reuseID, ofType: "nib") != nil {
        let nib = UINib(nibName: cellClass.reuseID, bundle: bundle)
        register(nib, forCellReuseIdentifier: cellClass.reuseID)
    } else {
        register(cellClass.self, forCellReuseIdentifier: cellClass.reuseID)
    }
}

ব্যাখ্যা:

  1. Reusableপ্রোটোকল তার শ্রেণীর নাম থেকে সেল আইডি উত্পন্ন করে। আপনি কনভেনশনটি অনুসরণ করেছেন তা নিশ্চিত করুন:cell ID == class name == nib name
  2. UITableViewCell কে কনর্ফাম করে Reusable প্রোটোকল।
  3. UITableView এক্সটেনশন নীব বা শ্রেণীর মাধ্যমে কোষ নিবন্ধকরণের পার্থক্যকে বিমূর্ত করে।

ব্যবহারের উদাহরণ:

override func viewDidLoad() {
    super.viewDidLoad()
    let tableView = UITableView()
    let cellClasses: [UITableViewCell.Type] = [PostCell.self, ProfileCell.self, CommentCell.self]
    cellClasses.forEach(tableView.register)
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: PostCell.self.reuseID) as? PostCell
    ...
    return cell
}

0

কোনও প্রচলিত উপায় আছে কিনা তা আমি জানি না, তবে এখানে আমার পদ্ধতিটি রয়েছে:

  • ভিউকন্ট্রোলারের জন্য একটি এক্সিব তৈরি করুন
  • ইউআইভিউউকন্ট্রোলারে ফাইলের মালিক শ্রেণি সেট করুন
  • দৃশ্যটি মুছুন এবং একটি ইউআইটিএবলভিউসেল যুক্ত করুন
  • আপনার কাস্টম শ্রেণিতে আপনার ইউআইটিএবলভিউসেল এর শ্রেণি সেট করুন
  • আপনার ইউআইটিএবলভিউসিলের পরিচয়কারী সেট করুন
  • আপনার ইউআইটিএবলভিউসেলতে আপনার ভিউ কন্ট্রোলার দৃশ্যের আউটলেট সেট করুন

এবং এই কোডটি ব্যবহার করুন:

MyCustomViewCell *cell = (MyCustomViewCell *)[_tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
  UIViewController* c = [[UIViewController alloc] initWithNibName:CellIdentifier bundle:nil];
  cell = (MyCustomViewCell *)c.view;
  [c release];
}

আপনার উদাহরণে, ব্যবহার করে

[nib objectAtIndex:0]

অ্যাপল xib- এ আইটেমগুলির ক্রম পরিবর্তন করলে ভাঙ্গতে পারে।


আমার জন্য, এর ফলে সর্বদা একটি নতুন উদাহরণ তৈরি হয়। Dequeue প্রতিবার শূন্য ফিরে আসবে বলে মনে হচ্ছে।
অদ্ভুত

0
 NSString *CellIdentifier = [NSString stringWithFormat:@"cell %ld %ld",(long)indexPath.row,(long)indexPath.section];


    NewsFeedCell *cell = (NewsFeedCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    cell=nil;

    if (cell == nil)
    {
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"NewsFeedCell" owner:nil options:nil];

        for(id currentObject in topLevelObjects)
        {
            if([currentObject isKindOfClass:[NewsFeedCell class]])
            {
                cell = (NewsFeedCell *)currentObject;
                break;
            }
        }
}
return cell;

0

এই এক্সটেনশনের জন্য Xcode7 বিটা 6 দরকার

extension NSBundle {
    enum LoadViewError: ErrorType {
        case ExpectedXibToExistButGotNil
        case ExpectedXibToContainJustOneButGotDifferentNumberOfObjects
        case XibReturnedWrongType
    }

    func loadView<T>(name: String) throws -> T {
        let topLevelObjects: [AnyObject]! = loadNibNamed(name, owner: self, options: nil)
        if topLevelObjects == nil {
            throw LoadViewError.ExpectedXibToExistButGotNil
        }
        if topLevelObjects.count != 1 {
            throw LoadViewError.ExpectedXibToContainJustOneButGotDifferentNumberOfObjects
        }
        let firstObject: AnyObject! = topLevelObjects.first
        guard let result = firstObject as? T else {
            throw LoadViewError.XibReturnedWrongType
        }
        return result
    }
}

একটি এক্স ফাইল তৈরি করুন যাতে মাত্র 1 টি কাস্টম ইউআইটিএবলভিউসেল রয়েছে।

এটি লোড করুন।

let cell: BacteriaCell = try NSBundle.mainBundle().loadView("BacteriaCell")

0
 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

            let cellReuseIdentifier = "collabCell"
            var cell:collabCell! = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as? collabCell
            if cell == nil {
                tableView.register(UINib(nibName: "collabCell", bundle: nil), forCellReuseIdentifier: cellReuseIdentifier)
                cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! collabCell!
            }


            return cell

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