কোনও ইউআইটিএবল ভিউসেল এর অ্যাকসেসরিভিউয়ের জন্য একটি কাস্টম চিত্র ব্যবহার করা এবং এটি ইউআইটিএবলভিউডেলিগেটে সাড়া দেয়


139

আমি সেলটির জন্য একইসাথে একটি কাস্টমযুক্ত টানা UITableViewCell ব্যবহার করছি accessoryView। অ্যাকসেসরিভিউয়ের জন্য আমার সেটআপটি এরকম কিছু মাধ্যমে ঘটে:

UIImage *accessoryImage = [UIImage imageNamed:@"accessoryDisclosure.png"];
UIImageView *accImageView = [[UIImageView alloc] initWithImage:accessoryImage];
accImageView.userInteractionEnabled = YES;
[accImageView setFrame:CGRectMake(0, 0, 28.0, 28.0)];
self.accessoryView = accImageView;
[accImageView release];

এছাড়াও যখন ঘরটি শুরু করা হয় তখন initWithFrame:reuseIdentifier:আমি নীচের সম্পত্তিটি সেট করে দেওয়ার বিষয়টি নিশ্চিত করে ব্যবহার করি:

self.userInteractionEnabled = YES;

দুর্ভাগ্যক্রমে আমার ইউআইটিএবলভিউ ডেলেগেটে, আমার tableView:accessoryButtonTappedForRowWithIndexPath:পদ্ধতিটি (10 বার পুনরাবৃত্তি করার চেষ্টা করুন) ট্রিগার হচ্ছে না। প্রতিনিধি অবশ্যই যথাযথভাবে বিরক্ত হয়ে গেছে।

কী অনুপস্থিত হতে পারে?

সবাইকে ধন্যবাদ.

উত্তর:


228

দুর্ভাগ্যক্রমে এই পদ্ধতিটি কল করা হয় না যদি আপনি পূর্বনির্ধারিত ধরণের কোনওটি ব্যবহার না করে অভ্যন্তরীণ বোতামের প্রকার সরবরাহ না করেন। আপনার নিজের ব্যবহার করতে, আপনাকে একটি বোতাম বা অন্যান্য ইউআইসিএন্ট্রোল সাবক্লাস হিসাবে নিজের আনুষাঙ্গিক তৈরি করতে হবে (আমি কোনও -buttonWithType:UIButtonTypeCustomইউআইআইভিউ ভিউ ব্যবহারের পরিবর্তে বোতামটির চিত্র ব্যবহার এবং সেট করতে একটি বোতামের পরামর্শ দেব)।

আমি আউটপোস্টে ব্যবহার করি এমন কিছু জিনিস যা মানক উইজেটগুলির যথেষ্ট পরিমাণকে কাস্টমাইজ করে (কিছুটা সামান্য, আমাদের টিল রঙের সাথে মেলে) যে আমি নিজের ইউআইটিএবভিউ কনট্রোলার মধ্যস্থতাকার সাবক্লাসটি ব্যবহার করে অন্য সমস্ত টেবিল দর্শনের জন্য ইউটিলিটি কোডটি ধরে রাখছি (তারা এখন সাবক্লাস) OPTableViewController)।

প্রথমত, এই ফাংশনটি আমাদের কাস্টম গ্রাফিক ব্যবহার করে একটি নতুন বিশদ প্রকাশ বোতামটি দেয়:

- (UIButton *) makeDetailDisclosureButton
{
    UIButton * button = [UIButton outpostDetailDisclosureButton];

[button addTarget: self
               action: @selector(accessoryButtonTapped:withEvent:)
     forControlEvents: UIControlEventTouchUpInside];

    return ( button );
}

এটি শেষ হয়ে গেলে বোতামটি এই রুটিনটিকে কল করবে, যারপরে আনুষঙ্গিক বোতামগুলির জন্য মানক UITableViewDelegate রুটিন ফিড করে:

- (void) accessoryButtonTapped: (UIControl *) button withEvent: (UIEvent *) event
{
    NSIndexPath * indexPath = [self.tableView indexPathForRowAtPoint: [[[event touchesForView: button] anyObject] locationInView: self.tableView]];
    if ( indexPath == nil )
        return;

    [self.tableView.delegate tableView: self.tableView accessoryButtonTappedForRowWithIndexPath: indexPath];
}

এই ফাংশনটি বোতামের সরবরাহিত ইভেন্ট থেকে একটি স্পর্শের টেবিল ভিউতে অবস্থান পেয়ে এবং সারিটির সূচক পথটির জন্য টেবিলের ভিউ জিজ্ঞাসা করে সারিটি চিহ্নিত করে।


ধন্যবাদ জিম আমি লজ্জা পেয়েছি 20 মিনিটেরও বেশি সময় ব্যয় করে কেন আমি কাস্টম ইমেজভিউ দিয়ে এটি করতে পারি না। আমি কেবল দেখেছি কীভাবে এটি অ্যাপলের নমুনা অ্যাকসেসরি অ্যাপে করা যায়। আপনার উত্তরটি ভালভাবে ব্যাখ্যা এবং নথিভুক্ত করা হয়েছে যদিও আমি এটিকে চিহ্নিত করছি এবং এটিকে প্রায় রাখছি। আবার ধন্যবাদ. :-)

জিম, দুর্দান্ত উত্তর। একটি সম্ভাব্য সমস্যা (কমপক্ষে আমার শেষের দিকে) - বোতামটিতে নিবন্ধটি পেতে আমাকে নীচের লাইনটি যুক্ত করতে হয়েছিল: बटन.userInterationEn सक्षम = হ্যাঁ;
মাইক লরেন্স

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

3
এটি আপনার হার্ড-কোড করা প্রয়োজন self.tableView। আপনি যদি জানেন না যে কোন টেবিলভিউতে সারি রয়েছে?
ব্যবহারকারী 102008

4
@ রায়ানজেএম আমি ভাবতাম যে হিটটেষ্ট করা ওভারকিল এবং ট্যাগগুলি যথেষ্ট হবে। আমি আমার কোডের কিছুতে ট্যাগ আইডিয়াটি ব্যবহার করেছি। তবে আজ আমি একটি সমস্যার মুখোমুখি হয়েছি যেখানে ব্যবহারকারী নতুন সারি যুক্ত করতে পারে। এটি ট্যাগ ব্যবহার করে হ্যাককে হত্যা করে। জিম ডোভির পরামর্শ দেওয়া সমাধান (এবং অ্যাপলের নমুনা
কোডটিতে

77

আমি এই ওয়েবসাইটটি খুব সহায়ক বলে মনে করেছি: আইফোনে আপনার ইউটিবেলভিউয়ের জন্য কাস্টম আনুষাঙ্গিক দেখুন

সংক্ষেপে, এটিকে ব্যবহার করুন cellForRowAtIndexPath::

UIImage *image = (checked) ? [UIImage imageNamed:@"checked.png"] : [UIImage imageNamed:@"unchecked.png"];

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect frame = CGRectMake(0.0, 0.0, image.size.width, image.size.height);
button.frame = frame;
[button setBackgroundImage:image forState:UIControlStateNormal];

[button addTarget:self action:@selector(checkButtonTapped:event:)  forControlEvents:UIControlEventTouchUpInside];
button.backgroundColor = [UIColor clearColor];
cell.accessoryView = button;

তারপরে, এই পদ্ধতিটি প্রয়োগ করুন:

- (void)checkButtonTapped:(id)sender event:(id)event
{
    NSSet *touches = [event allTouches];
    UITouch *touch = [touches anyObject];
    CGPoint currentTouchPosition = [touch locationInView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint: currentTouchPosition];

    if (indexPath != nil)
    {
        [self tableView: self.tableView accessoryButtonTappedForRowWithIndexPath: indexPath];
    }
}

4
অ্যাপল তাদের দস্তাবেজে তাদের নমুনা
কোডটিতে

ফ্রেম সেট করা আমার জন্য অনুপস্থিত অংশ ছিল। যতক্ষণ আপনি কোনও পাঠ্যও চান না ততক্ষণ আপনি কেবল পটভূমি (পটভূমির পরিবর্তে) সেট করতে পারেন।
জেরেমি হিকস

1
লিঙ্কটি @ রিচার্ডদাসের উত্তরে ভেঙে গেছে। নতুন লিঙ্ক: বিকাশকারী।
অ্যাপ্লিকেশন

7

আমার দৃষ্টিভঙ্গি একটি UITableViewCellসাবক্লাস তৈরি করা এবং যুক্তিটি অন্তর্ভুক্ত করা উচিত যা এর মধ্যে স্বাভাবিকের UITableViewDelegateপদ্ধতিটিকে কল করে ।

// CustomTableViewCell.h
@interface CustomTableViewCell : UITableViewCell

- (id)initForIdentifier:(NSString *)reuseIdentifier;

@end

// CustomTableViewCell.m
@implementation CustomTableViewCell

- (id)initForIdentifier:(NSString *)reuseIdentifier;
{
    // the subclass specifies style itself
    self = [super initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:reuseIdentifier];
    if (self) {
        // get the button elsewhere
        UIButton *accBtn = [ViewFactory createTableViewCellDisclosureButton];
        [accBtn addTarget: self
                   action: @selector(accessoryButtonTapped:withEvent:)
         forControlEvents: UIControlEventTouchUpInside];
        self.accessoryView = accBtn;
    }
    return self;
}

#pragma mark - private

- (void)accessoryButtonTapped:(UIControl *)button withEvent:(UIEvent *)event
{
    UITableViewCell *cell = (UITableViewCell*)button.superview;
    UITableView *tableView = (UITableView*)cell.superview;
    NSIndexPath *indexPath = [tableView indexPathForCell:cell];
    [tableView.delegate tableView:tableView accessoryButtonTappedForRowWithIndexPath:indexPath];
}

@end

এটি সেরা উত্তর। তবে button.superview, cell.superviewএবং [tableView.delegate tableView:...]যথেষ্ট নিরাপদ নয়।
মিঃ মিং

3

উপরে জিম ডোভির উত্তরের একটি বর্ধন:

আপনি যখন আপনার ইউআইটিএবলভিউ দিয়ে কোনও ইউআইসন্ধানবারকন্ট্রোলার ব্যবহার করেন তখন সাবধান হন। সেক্ষেত্রে আপনি পরীক্ষা করে দেখতে চান self.searchDisplayController.activeএবং self.searchDisplayController.searchResultsTableViewপরিবর্তে ব্যবহার করতে চান self.tableView। অন্যথায় আপনি অনুসন্ধানডিসপ্লে কন্ট্রোলার সক্রিয় থাকাকালীন অপ্রত্যাশিত ফলাফলগুলি পাবেন, বিশেষত যখন অনুসন্ধান ফলাফলগুলি স্ক্রোল করা থাকে।

উদাহরণ স্বরূপ:

- (void) accessoryButtonTapped:(UIControl *)button withEvent:(UIEvent *)event
{
    UITableView* tableView = self.tableView;
    if(self.searchDisplayController.active)
        tableView = self.searchDisplayController.searchResultsTableView;

    NSIndexPath * indexPath = [tableView indexPathForRowAtPoint:[[[event touchesForView:button] anyObject] locationInView:tableView]];
    if(indexPath)
       [tableView.delegate tableView:tableView accessoryButtonTappedForRowWithIndexPath:indexPath];
}

2
  1. বোতামগুলির ট্যাগগুলির জন্য ম্যাক্রো সংজ্ঞায়িত করুন:

    #define AccessoryViewTagSinceValue 100000 // (AccessoryViewTagSinceValue * sections + rows) must be LE NSIntegerMax
  2. একটি ঘর তৈরি করার সময় বোতামটি তৈরি করুন এবং সেল.অ্যাকসেসরিভিউ সেট করুন

    UIButton *accessoryButton = [UIButton buttonWithType:UIButtonTypeContactAdd];
    accessoryButton.frame = CGRectMake(0, 0, 30, 30);
    [accessoryButton addTarget:self action:@selector(accessoryButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
    cell.accessoryView = accessoryButton;
  3. সেলআইএকসেসরিভিউ.ট্যাগটি ইউআইটিএবলভিউ ডেটাসোর্স পদ্ধতিতে-টেবিলভিউতে ইনডেক্সপথ দ্বারা সেট করুন: সেলফরআরআউটআইডেক্সপথ:

    cell.accessoryView.tag = indexPath.section * AccessoryViewTagSinceValue + indexPath.row;
  4. বোতামগুলির জন্য ইভেন্ট হ্যান্ডলার

    - (void) accessoryButtonTapped:(UIButton *)button {
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:button.tag % AccessoryViewTagSinceValue
                                                    inSection:button.tag / AccessoryViewTagSinceValue];
    
        [self.tableView.delegate tableView:self.tableView accessoryButtonTappedForRowWithIndexPath:indexPath];
    }
  5. UITableViewDelegate পদ্ধতিটি প্রয়োগ করুন

    - (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
        // do sth.
    }

1
tagপরম প্রয়োজন ব্যতীত কারও ব্যবহার করা উচিত নয় , অন্যান্য সমাধান সন্ধান করুন।
প্রাণবন্ত

2

বোতামটি আলতো চাপলে আপনি কোনও ইউআইটিএবলভিউসেল সাবক্লাসের অভ্যন্তরে নিম্নলিখিত পদ্ধতিটি কল করতে পারেন

 -(void)buttonTapped{
     // perform an UI updates for cell

     // grab the table view and notify it using the delegate
     UITableView *tableView = (UITableView *)self.superview;
     [tableView.delegate tableView:tableView accessoryButtonTappedForRowWithIndexPath:[tableView indexPathForCell:self]];

 }

1

ইয়াঞ্চেঙ্কো পদ্ধতির সাথে আমাকে যুক্ত করতে হয়েছিল: [accBtn setFrame:CGRectMake(0, 0, 20, 20)];

আপনি যদি নিজের টেবিলসেলটি কাস্টমাইজ করতে xib ফাইল ব্যবহার করেন তবে initWithStyle: reuseIdentifier: কল হবে না।

পরিবর্তে ওভাররাইড করুন:

-(void)awakeFromNib
{
//Put your code here 

[super awakeFromNib];

}

1

UIControlসাধারণের UIButtonপরিবর্তে ইভেন্ট প্রেরণটি (উদাহরণস্বরূপ ক ) সঠিকভাবে পেতে আপনাকে অবশ্যই একটি ব্যবহার করতে হবে UIView/UIImageView


1

সুইফট 5

এই পদ্ধতির UIButton.tagবুনিয়াদি বিট-শিফটিং ব্যবহার করে সূচিপথটি সঞ্চয় করতে ব্যবহার করে। আপনার কাছে 65535 টির বেশি সারি বা সারি না থাকা পর্যন্ত 32 এবং 64 বিট সিস্টেমে অ্যাপ্রোচটি কাজ করবে।

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

    let cell = tableView.dequeueReusableCell(withIdentifier: "cellId")
    let accessoryButton = UIButton(type: .custom)
    accessoryButton.setImage(UIImage(named: "imageName"), for: .normal)
    accessoryButton.sizeToFit()
    accessoryButton.addTarget(self, action: #selector(handleAccessoryButton(sender:)), for: .touchUpInside)

    let tag = (indexPath.section << 16) | indexPath.row
    accessoryButton.tag = tag
    cell?.accessoryView = accessoryButton

}

@objc func handleAccessoryButton(sender: UIButton) {
    let section = sender.tag >> 16
    let row = sender.tag & 0xFFFF
    // Do Stuff
}

0

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

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