সুইফটে নিব থেকে কাস্টম ইউআইটিএবলভিউসেল


139

আমি নিব থেকে কাস্টম টেবিল ভিউ সেল তৈরি করার চেষ্টা করছি। আমি এই নিবন্ধ এখানে উল্লেখ করছি । আমি দুটি সমস্যার মুখোমুখি হয়েছি।

আমি এটিতে টানা একটি ইউআইটিএবলভিউসেল বস্তু সহ একটি .xib ফাইল তৈরি করেছি। আমি এর একটি সাবক্লাস তৈরি করেছি UITableViewCellএবং এটিকে ঘরের শ্রেণি এবং সেলটি পুনরায় ব্যবহারযোগ্য সনাক্তকারী হিসাবে সেট করেছি ।

import UIKit

class CustomOneCell: UITableViewCell {

    @IBOutlet weak var middleLabel: UILabel!
    @IBOutlet weak var leftLabel: UILabel!
    @IBOutlet weak var rightLabel: UILabel!

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

    override init(style: UITableViewCellStyle, reuseIdentifier: String!) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
    }

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

ইউআইটিএবল ভিউ কনট্রোলারটিতে আমার এই কোডটি রয়েছে,

import UIKit

class ViewController: UITableViewController, UITableViewDataSource, UITableViewDelegate {

    var items = ["Item 1", "Item2", "Item3", "Item4"]

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

    // MARK: - UITableViewDataSource
    override func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
        return items.count
    }

    override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
        let identifier = "Cell"
        var cell: CustomOneCell! = tableView.dequeueReusableCellWithIdentifier(identifier) as? CustomOneCell
        if cell == nil {
            tableView.registerNib(UINib(nibName: "CustomCellOne", bundle: nil), forCellReuseIdentifier: identifier)
            cell = tableView.dequeueReusableCellWithIdentifier(identifier) as? CustomOneCell
        }

        return cell
    }
}

এই কোডটি কোনও ত্রুটি মেনে চলে না তবে আমি যখন এটি সিমুলেটরটিতে চালিত করি তখন এটি দেখতে এটির মতো লাগে।

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

স্টোরিবোর্ডের ইউআইটিএবলভিউ কনট্রোলারে আমি সেলটির জন্য কিছু করি নি। খালি শনাক্তকারী এবং কোনও সাবক্লাস নেই। আমি প্রোটোটাইপ সেলে সেল শনাক্তকারী যুক্ত করার চেষ্টা করেছি এবং এটি আবার চালিয়েছি তবে আমি একই ফলাফল পেয়েছি।

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

override func tableView(tableView: UITableView!, willDisplayCell cell: CustomOneCell!, forRowAtIndexPath indexPath: NSIndexPath!) {

    cell.middleLabel.text = items[indexPath.row]
    cell.leftLabel.text = items[indexPath.row]
    cell.rightLabel.text = items[indexPath.row]
}

হিসাবে নিবন্ধ আমি উল্লেখ দেখানো আমি পরিবর্তন cellপরামিতি ধরন ফর্ম UITableViewCellথেকে CustomOneCellযা UITableViewCell আমার উপশ্রেণী হয়। তবে আমি নিম্নলিখিত ত্রুটি পেয়েছি,

নির্বাচক 'টেবিল ভিউ: উইল ডিসপ্লেকেল: ফরআউট ইন্ডেক্সপথ:' এর সাথে বেমানান টাইপ রয়েছে '(ওআইটিএলভিউ!, কাস্টমঅনসেল!, এনএসআইন্ডেক্সপথ!) -> ()'

এই ত্রুটিগুলি কীভাবে সমাধান করবেন সে সম্পর্কে কারও কোনও ধারণা আছে? এগুলি অবজেক্টিভ-সি-তে ভাল কাজ করেছে বলে মনে হয়েছিল।

ধন্যবাদ.

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

উত্তর:


213

সুইফ্ট 5 এবং আইওএস 12.2 এর সাহায্যে আপনার সমস্যাটি সমাধান করার জন্য আপনার নীচের কোডটি ব্যবহার করে দেখুন:

CustomCell.swift

import UIKit

class CustomCell: UITableViewCell {

    // Link those IBOutlets with the UILabels in your .XIB file
    @IBOutlet weak var middleLabel: UILabel!
    @IBOutlet weak var leftLabel: UILabel!
    @IBOutlet weak var rightLabel: UILabel!

}

TableViewController.swift

import UIKit

class TableViewController: UITableViewController {

    let items = ["Item 1", "Item2", "Item3", "Item4"]

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.register(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "CustomCell")
    }

    // MARK: - UITableViewDataSource

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

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell

        cell.middleLabel.text = items[indexPath.row]
        cell.leftLabel.text = items[indexPath.row]
        cell.rightLabel.text = items[indexPath.row]

        return cell
    }

}

নীচের চিত্রটি কোনও সীমাবদ্ধতার একটি সেট দেখায় যা এক্সকোডের কোনও সীমাবদ্ধতার অস্পষ্টতা বার্তা ছাড়াই প্রদত্ত কোডের সাথে কাজ করে:

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


1
উত্তরের জন্য ধন্যবাদ. তবে সেটাও কার্যকর হয়নি। আমার কি টেবিল ভিউ কন্ট্রোলারে কিছু পরিবর্তন করার দরকার আছে? কারণ এটি এখনও প্রোটোটাইপ সেলগুলিতে সেট করেছে।
ইসুড়ু

1
প্রোটোটাইপ কোষ ব্যবহার করা চালিয়ে যান। তবে নিশ্চিত হয়ে নিন যে আপনি ভাল অটো বিন্যাসের সীমাবদ্ধতা সেট করেছেন (যদি আপনি অটো লেআউট ব্যবহার করেন)।
ইমানো পেটিট

1
আমি যে সমস্যাটি করছি তা প্রদর্শন করে এখানে একটি পরীক্ষার প্রকল্প আপলোড করেছি। আপনার যদি সময় থাকে তবে দয়া করে এটি একবার দেখে নিতে পারেন?
ইসুরু

1
আপনার পরীক্ষার প্রকল্প এটি নিশ্চিত করে: আমি আপনার .xib ফাইলে আপনার কাস্টম ঘরে কিছু স্বয়ংক্রিয় বিন্যাসের সীমাবদ্ধতা সেট করার পরে আমি আপনার অ্যাপটিকে ঠিকঠাক করতে সক্ষম হয়েছি। আপনার অটো লেআউট সম্পর্কে আরও জানতে হলে এই ভিডিওটি একবার দেখুন ।
ইমানু পেটিট

2
@ কিরিলকুদায়েভ এটির নাম সুইফট 4-এ নয় তবে সুইফট 3-এ রাখা হয়েছে: আমি আপনার সম্পাদনাটি স্থির করেছি।
সিউর

30

এখানে সুইফট 2 এবং এক্সকোড 7.3 ব্যবহার করে আমার দৃষ্টিভঙ্গি দেওয়া হল। এই উদাহরণটি দুটি .xib ফাইল লোড করতে একটি একক ভিউ কন্ট্রোলার ব্যবহার করবে - একটি ইউআইটিবেল ভিউর জন্য এবং একটি ইউআইটিবেবলসভিউয়ের জন্য।

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

এই উদাহরণের জন্য আপনি একটি UITableView সরাসরি খালি টেবিলিব .xib ফাইলের মধ্যে ফেলে দিতে পারেন । ভিতরে, ফাইলের মালিককে আপনার ভিউকন্ট্রোলার শ্রেণিতে সেট করুন এবং টেবিল ভিউয়ের রেফারেন্স দিতে একটি আউটলেট ব্যবহার করুন।

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

এবং

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

এখন, আপনার ভিউ কন্ট্রোলারে, আপনি টেবিলভিউটি যেমন পছন্দ করেন তেমনই ডেলিগেট করতে পারেন

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!

    ...

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        // Table view delegate
        self.tableView.delegate = self
        self.tableView.dataSource = self

        ...

আপনার কাস্টম সেলটি তৈরি করতে, আবার একটি টেবিল ভিউ সেল অবজেক্টটি একটি খালি টেবিলসেলনিব .xib ফাইলে ফেলে দিন। এবার সেল .xib ফাইলে আপনাকে কোনও "মালিক" নির্দিষ্ট করতে হবে না তবে আপনাকে একটি কাস্টম ক্লাস এবং "টেবিলসিল আইডি" এর মতো একটি সনাক্তকারী নির্দিষ্ট করতে হবে

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

আপনার যেমন প্রয়োজন এমন আউটলেটগুলি সহ আপনার সাবক্লাস তৈরি করুন

class TableCell: UITableViewCell {

    @IBOutlet weak var nameLabel: UILabel!

}

অবশেষে ... আপনার ভিউ কন্ট্রোলারে ফিরে এসে আপনি পুরো জিনিসটি লোড এবং প্রদর্শন করতে পারেন

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    // First load table nib
    let bundle = NSBundle(forClass: self.dynamicType)
    let tableNib = UINib(nibName: "TableNib", bundle: bundle)
    let tableNibView = tableNib.instantiateWithOwner(self, options: nil)[0] as! UIView

    // Then delegate the TableView
    self.tableView.delegate = self
    self.tableView.dataSource = self

    // Set resizable table bounds
    self.tableView.frame = self.view.bounds
    self.tableView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]

    // Register table cell class from nib
    let cellNib = UINib(nibName: "TableCellNib", bundle: bundle)
    self.tableView.registerNib(cellNib, forCellReuseIdentifier: self.tableCellId)

    // Display table with custom cells
    self.view.addSubview(tableNibView)

}

কোডটি দেখায় যে কীভাবে আপনি কেবল একটি নিব ফাইল (টেবিল) লোড করতে এবং প্রদর্শন করতে পারেন এবং দ্বিতীয়টি কীভাবে সেল ব্যবহারের জন্য নিব রেজিস্ট্রেশন করতে পারেন।

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


2
এই লাইনে "টেবিলসিলিডি" কী আপনি তা ব্যাখ্যা করতে পারেন .... সেল্ফ.ট্যাবলভিউ.গ্রিস্টারনিব (সেলনিব, সেলসিরিউজআইডেন্টিফায়ার: সেল্ফ.ট্যাবলসেল্ড) .... কারণ আপনি এটি কি সংজ্ঞায়িত করেন নি। এবং আপনি xib এ ম্যানুয়ালি শনাক্তকারীকে সংজ্ঞায়িত করতে পারবেন না ... এটি সংজ্ঞায়িত করার কোনও বিকল্প নেই
PRADIP KUMAR

1
ইন্টারফেস বিল্ডারে, আপনি যখন টেবিলসেল তৈরি করেন, "গুণাবলী পরিদর্শক" তে আপনি একটি শনাক্তকারীকে সংজ্ঞায়িত করেন। একই আইডেন্টিফায়ারটি হ'ল আপনি নিজের নিয়ামকটিতে অবজেক্টটি উল্লেখ করতে ব্যবহার করেন। let tableCellId = "myAwesomeCell"। আপনাকে সাহায্য করার জন্য আমি অন্য চিত্র যুক্ত করেছি।
ইন্টারনেট-নিকো 21

16

সুইফট 4

নিব রেজিস্ট্রেশন করুন

override func viewDidLoad() {
    super.viewDidLoad()
    tblMissions.register(UINib(nibName: "MissionCell", bundle: nil), forCellReuseIdentifier: "MissionCell")
}

টেবিলভিউ ডেটাসোর্সে

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
          guard let cell = tableView.dequeueReusableCell(withIdentifier: "MissionCell", for: indexPath) as? MissionCell else { return UITableViewCell() }
          return cell
    }

9

স্ক্রিনশট সহ বিশদ সমাধান

  1. একটি খালি ইউজার ইন্টারফেস ফাইল তৈরি করুন এবং নাম দিন MyCustomCell.xib

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

  1. একটি যোগ করুন UITableViewCellআপনার xib ফাইল রুট এবং অন্য কোন চাক্ষুষ উপাদান আপনি চান হিসাবে।

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

  1. MyCustomCellসাবক্লাস হিসাবে শ্রেণীর নাম সহ কোকো টাচ ক্লাস ফাইল তৈরি করুন UITableViewCell

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

  1. আপনার কাস্টম টেবিল ভিউ সেলের জন্য কাস্টম ক্লাস সেট করুন এবং সনাক্তকারী পুনরায় ব্যবহার করুন।

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

  1. সহকারী সম্পাদক খুলুন এবং ctrl+dragআপনার চাক্ষুষ উপাদানগুলির জন্য আউটলেটগুলি তৈরি করুন।

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

  1. UIViewControllerআপনার কাস্টম সেলটি ব্যবহার করতে একটি কনফিগার করুন ।
class MyViewController: UIViewController {

    @IBOutlet weak var myTable: UITableView!

    override func viewDidLoad {
        super.viewDidLoad()

        let nib = UINib(nibName: "MyCustomCell", bundle: nil)
        myTable.register(nib, forCellReuseIdentifier: "MyCustomCell")
        myTable.dataSource = self
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: "MyCustomCell") as? MyCustomCell {
            cell.myLabel.text = "Hello world."
            return cell
        }
        ...
    }
}

আপনি আমার দিন বাঁচিয়েছেন। আমি MyHeaderView.swiftকাস্টম সেল জন্য অনুলিপি ছিল । .swiftহেডারের জন্য দৃশ্য নেই identifierমধ্যে Table View Cellমধ্যে Attribute Inspector। সুতরাং ... রান সময় ত্রুটি ঘটেছে।
mazend

যাইহোক, আমরা কেন .swiftএবং ভিতরে শনাক্তকারীদের জন্য একই নাম ঘোষণা করব tableView?.register(blahblah, forCellReuseIdentifier: "myCell")? আমি ভেবেছিলাম তাদের একটির দরকার নেই তবে .. আমি দেখতে পেলাম যে দু'টিই অপরিহার্য।
mazend

উম .. এটা হয়তো কারণ .. .xibকাস্টম সেল জন্য একাধিক থাকতে পারে UITableViewCellতাই .. .xibযথেষ্ট নয় .. সঠিক সেল পাবেন।
mazend

5

আপনি নীব হিসাবে আপনার নিব নিবন্ধন করেন নি:

tableView.registerNib(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "CustomCell")

4

অন্য পদ্ধতি যা আপনার পক্ষে কাজ করতে পারে (এটি আমি এটি কীভাবে করি) একটি ক্লাস নিবন্ধন করছে।

ধরে নিন আপনি নীচের মত একটি কাস্টম টেবিল তৈরি করেছেন:

class UICustomTableViewCell: UITableViewCell {...}

তারপরে আপনি এই সেলটি যে কোনও ইউআইটিএবলভিউ কনট্রোলারটিতে "রেজিস্টারক্লাস" দিয়ে প্রদর্শিত হবে তাতে নিবন্ধভুক্ত করতে পারেন:

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.registerClass(UICustomTableViewCell.self, forCellReuseIdentifier: "UICustomTableViewCellIdentifier")
}

এবং আপনি সারি পদ্ধতিতে ঘরে যেমন প্রত্যাশা করেছিলেন তেমন কল করতে পারেন:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("UICustomTableViewCellIdentifier", forIndexPath: indexPath) as! UICustomTableViewCell
    return cell
}

3

ফিক্স জন্য "উপেক্ষা পদ্ধতি ... বেমানান টাইপ হয়েছে ..." ত্রুটি আমি ফাংশন ঘোষণা পরিবর্তিত করে থাকেন

override func tableView(tableView: (UITableView!), 
                        cellForRowAtIndexPath indexPath: (NSIndexPath!)) 
    -> UITableViewCell {...}

(ছিল -> UITableViewCell!- শেষে বিস্ময়কর চিহ্ন সহ)


2

দ্রুত 4.1.2

xib।

ইমেজসেল 2.সুইফ্ট তৈরি করুন

ধাপ 1

import UIKit

class ImageCell2: UITableViewCell {

    @IBOutlet weak var imgBookLogo: UIImageView!
    @IBOutlet weak var lblTitle: UILabel!
    @IBOutlet weak var lblPublisher: UILabel!
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }

}

ধাপ ২ . ভিউকন্ট্রোলার ক্লাস অনুসারে

  import UIKit

    class ImageListVC: UIViewController,UITableViewDataSource,UITableViewDelegate {
    @IBOutlet weak var tblMainVC: UITableView!

    var arrBook : [BookItem] = [BookItem]()

    override func viewDidLoad() {
        super.viewDidLoad()
         //Regester Cell
        self.tblMainVC.register(UINib.init(nibName: "ImageCell2", bundle: nil), forCellReuseIdentifier: "ImageCell2")
        // Response Call adn Disply Record
        APIManagerData._APIManagerInstance.getAPIBook { (itemInstance) in
            self.arrBook = itemInstance.arrItem!
            self.tblMainVC.reloadData()
        }
    }
    //MARK: DataSource & delegate
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.arrBook.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//    [enter image description here][2]
        let cell  = tableView.dequeueReusableCell(withIdentifier: "ImageCell2") as! ImageCell2
        cell.lblTitle.text = self.arrBook[indexPath.row].title
        cell.lblPublisher.text = self.arrBook[indexPath.row].publisher
        if let authors = self.arrBook[indexPath.row].author {
            for item in authors{
                print(" item \(item)")
            }
        }
        let  url  = self.arrBook[indexPath.row].imageURL
        if url == nil {
            cell.imgBookLogo.kf.setImage(with: URL.init(string: ""), placeholder: UIImage.init(named: "download.jpeg"))
        }
        else{
            cell.imgBookLogo.kf.setImage(with: URL(string: url!)!, placeholder: UIImage.init(named: "download.jpeg"))
        }
        return cell
    }
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 90
    } 

}

2

আমাকে নিশ্চিত করতে হয়েছিল যে আউটলেটটি তৈরি করার সময় নির্দিষ্ট করে রাখতে হবে যে আমি ঘরের দিকে ঝুঁকছি, বস্তুর মালিক নয়। যখন মেনুটির নামটি উপস্থিত হয় তখন আপনাকে এটি 'অবজেক্ট' ড্রপডাউন মেনুতে নির্বাচন করতে হবে। অবশ্যই আপনাকে অবশ্যই সেলটি আপনার ক্লাস হিসাবে ঘোষণা করতে হবে, কেবল 'টেবিলভিউসেলক্লাস' নয়। নইলে আমি ক্লাসটি কী মেনে চলতে থাকব না।


1

ইউআইটিএবলভিউসেল সহ ক্লাসে একটি এক্সবি নিন । পুনর্নির্মাণ অনুযায়ী ইউআই সেট করুন এবং আইবিউটলেট বরাদ্দ করুন। এটির মতো সারণী দর্শনটির সেলফরআরআউট () এ ব্যবহার করুন:

//MARK: - table method

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.arrayFruit.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    var cell:simpleTableViewCell? = tableView.dequeueReusableCell(withIdentifier:"simpleTableViewCell") as? simpleTableViewCell
    if cell == nil{
        tableView.register(UINib.init(nibName: "simpleTableViewCell", bundle: nil), forCellReuseIdentifier: "simpleTableViewCell")
        let arrNib:Array = Bundle.main.loadNibNamed("simpleTableViewCell",owner: self, options: nil)!
        cell = arrNib.first as? simpleTableViewCell
    }

    cell?.labelName.text = self.arrayFruit[indexPath.row]
    cell?.imageViewFruit.image = UIImage (named: "fruit_img")

    return cell!

}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
 return 100.0
}

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

100% কোনও সমস্যা ছাড়াই কাজ করছে (পরীক্ষিত)


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