user2845489 user2845489 - 1 year ago 73
iOS Question

Getting data from a textfield inside a prototype uicollectionviewcell

I have a UICollectionViewCell which is prototype cell, I have a textfield in it, which by default present in all of them. (which is what I want). I want to be able to when the user inputs a value in these textfields to be able to retrieve the data and the cell which the data was put into(maybe the number of the row). I have seen a few other related questions but none seems to work for me. Any ideas?

@interface ViewController ()
NSArray *collections, *numbers;
NSMutableArray *selectedItemsArray;
UICollectionViewCell *cell;
UITextView *text1Field;
NSIndexPath *indexPath1;
- (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
collections = [NSArray arrayWithObjects:@"starbucks_coffee.jpg", @"thai_shrimp_cake.jpg", @"vegetable_curry.jpg", @"white_chocolate_donut.jpg", nil];
selectedItemsArray = [NSMutableArray array];
numbers = [NSArray arrayWithObjects:@"1", @"2", @"3", @"4", nil];

- (void)didReceiveMemoryWarning
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
return collections.count;
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
static NSString *identifier = @"Cell";

cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];

UIImageView *imageview = (UIImageView *)[cell viewWithTag:100];
text1Field = (UITextView *)[cell viewWithTag:50];

imageview.image = [UIImage imageNamed:[collections objectAtIndex:indexPath.row]];

collectionView.allowsMultipleSelection = YES;

collectionView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"bg2.png"]];

return cell;


Answer Source

Implement the delegate method (void)textViewDidChange:(UITextView *)textView . You could use the tag property of the textView to distinguish which one was changed.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"MySpecialCell";
    MySpecialCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (!cell) {
        cell = [[MySpecialCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        cell.mySpecialTextView.delegate = self;
    cell.mySpecialTextView.tag = indexPath.row;
    return cell;

- (void)textViewDidChange:(UITextView *)textView
    int rowOfTextViewThatJustChanged = textView.tag;

Here's an approach that uses associated objects instead of tags.

static NSString *const kIndexPathKey = @"indexPathKey";

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"MultiSelectCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        UISwitch *switchView = [[UISwitch alloc] init];
        [switchView addTarget:self action:@selector(switchValueChanged:) forControlEvents:UIControlEventValueChanged];
        cell.accessoryView = switchView;

    UISwitch *switchView = (id)cell.accessoryView;
    [self setIndexPath:indexPath onSwitch:switchView];
    switchView.on = [self isIndexPathSelected:indexPath];

    id item = [self itemAtIndexPath:indexPath];
    cell.textLabel.text = safePerformSelector(item, self.itemDescriptionSelector);
    return cell;

- (void)switchValueChanged:(UISwitch *)sender {
    NSIndexPath *indexPath = [self indexPathOfSwitch:sender];
    [self setRowSelected:sender.isOn atIndexPath:indexPath];
    [self.delegate didSelectItem:[self itemAtIndexPath:indexPath] atIndexPath:indexPath selected:sender.isOn sender:self];

- (void)setIndexPath:(NSIndexPath *)indexPath onSwitch:(UISwitch *)switchView {
    [switchView setAssociatedObject:indexPath forKey:kIndexPathKey];

- (NSIndexPath *)indexPathOfSwitch:(UISwitch *)switchView {
    return [switchView associatedObjectForKey:kIndexPathKey];

@implementation NSObject (AssociatedObjects)

- (void)setAssociatedObject:(id)object forKey:(NSString *const)key {
    objc_setAssociatedObject(self, (__bridge const void *)(key), object, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

- (id)associatedObjectForKey:(NSString *const)key {
    return objc_getAssociatedObject(self, (__bridge const void *)(key));

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download