1

I'm developing an iOS app with latest SDK.

I have an UITableView with a lot of rows but I only show five rows. In other words, the user only can see five rows. He/she can scrolls the table, but only five rows are visible.

I want to make selectable the third row. The user only can select the third visible row.

I'm trying to simulate an UIPickerView first, because I'm using Core Data and all the code now works fine with UITableView delegate and, second, I don't know how to customize UIPickerView background and selection area.

How can I make the third visible row the only row selectable?

VansFannel
  • 45,055
  • 107
  • 359
  • 626
  • Might also want to make the rows snap to the top of first visible row. You can do this using the ScrollView delegate method. Added an example showing that. – LJ Wilson Mar 17 '13 at 01:16

3 Answers3

1

implement -[id<UITableViewDelegate> tableView:willSelectRowAtIndexPath:] like this:

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSArray *indexPaths = [tableView indexPathsForVisibleRows];
    if ([indexPaths objectAtIndex:2] isEqual:indexPath) {
        return indexPath;
    } else {
        return nil;
    }
}

More info here

Nick C
  • 645
  • 3
  • 6
1

Complete example along with snap to rows (by implementing ScrollView Delegate):

ViewController.h:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
    @property (weak, nonatomic) IBOutlet UITableView *myTableView;
@end

ViewController.m:

#import "ViewController.h"

static int kRowHeight = 92;
static int kArrayCount = 20;

@interface ViewController ()
@property (nonatomic, strong) NSMutableArray *tableViewData;

@end

@implementation ViewController
-(void)populateArray {
    for (int i=0; i<kArrayCount; i++) {
        [self.tableViewData addObject:[NSString stringWithFormat:@"String # %d",i]];
    }
    [self.myTableView reloadData];
}

#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
    return [self.tableViewData count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    cell.textLabel.text = [self.tableViewData objectAtIndex:indexPath.row];
    // Configure the cell...

    return cell;
}

#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Navigation logic may go here. Create and push another view controller.
    // Standard UIAlert Syntax
    UIAlertView *myAlert = [[UIAlertView alloc]
                            initWithTitle:@"Selected"
                            message:[NSString stringWithFormat:@"Selected Row %d", indexPath.row]
                            delegate:nil
                            cancelButtonTitle:@"OK"
                            otherButtonTitles:nil, nil];

    [myAlert show];

}

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSArray *indexPaths = [tableView indexPathsForVisibleRows];
    if ([[indexPaths objectAtIndex:2] isEqual:indexPath]) {
        return indexPath;
    } else {
        return nil;
    }
}


#pragma mark - ScrollView Delegate Methods (Make rows snap to position top)
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
                     withVelocity:(CGPoint)velocity
              targetContentOffset:(inout CGPoint *)targetContentOffset {
    int cellHeight = kRowHeight;
    *targetContentOffset = CGPointMake(targetContentOffset->x,
                                       targetContentOffset->y - (((int)targetContentOffset->y) % cellHeight));
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.tableViewData = [[NSMutableArray alloc] initWithCapacity:kArrayCount];
    [self populateArray];
    // Do any additional setup after loading the view, typically from a nib.
}

@end
LJ Wilson
  • 14,445
  • 5
  • 38
  • 62
0

You can use the array [self.tableView indexPathsForVisibleRows] to find out what indexPaths are visible. In the willSelectRowAtIndexPath method return nil for all but the third element.

To avoid highlighting you can also use this to set

cell.selectionStyle = UITableViewCellSelectionStyleNone;

In the CFRAIP method.

Richard Brown
  • 11,346
  • 4
  • 32
  • 43