Xcode didSelectRowAtIndexPath on tableview not called - xcode

I have been looking until 6 o'clock this morning, but I can't figure out why the didSelectRowAtIndexPath method is not being called. I am getting quite desparate on this one.
The tableview is shown properly, but I cannot succeed to enable the selection of a cell.
In the header file , I added:
#interface AlertsTable : UIViewController<UITableViewDelegate, UITableViewDataSource, CMPopTipViewDelegate>{
UITableView *TableView;
}
#property (nonatomic, retain) UITableView *TableView;
In the implementation file:
#synthesize TableView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
//Set the title
//Format Alerts table
//self.view.backgroundColor = [UIColor redColor];
CGFloat sideMargin = 10;
CGFloat topBottomMargin = 44;
CGFloat originX = sideMargin;
// compute width based on view size
CGFloat sizeWidth = (self.view.bounds.size.width - (sideMargin * 2));
CGFloat originY = topBottomMargin;
// compute height based on view size
CGFloat sizeHeight = (self.view.bounds.size.height - (topBottomMargin * 2));
//self.view.frame = CGRectMake(originX, originY, sizeWidth, sizeHeight);
self.TableView = [[UITableView alloc] initWithFrame:CGRectMake(originX, originY, sizeWidth, sizeHeight) style:UITableViewStylePlain];
//Initialize the array.
AlertsItems = [[NSMutableArray alloc] initWithObjects: #"Alert 1", #"Alert 2", #"Alert 3" , #"Alert 4", #"Alert 5", #"Alert 6", nil];
[self.TableView setDelegate:self];
[self.TableView setDataSource:self];
[self.view addSubview:TableView];
TableView.userInteractionEnabled = YES;
TableView.allowsSelection = YES;
TableView.allowsSelectionDuringEditing = YES;
NSLog(#"delegate:%# dataSource:%#", self.TableView.delegate, self.TableView.dataSource);
}
The delegate and datasource are both not nil on the check.
Note that the "Alertstable" inherits from a UIViewController, not a UITableViewController.
This is necessary due to the implementation I chose: the tableview is shown on a popupwindow shown on the screen (using another class that I took from the internet).
This is the didSelectRowAtIndexPath method:
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *alertString = [NSString stringWithFormat:#"Clicked on row #%d", [indexPath row]];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:alertString message:#"" delegate:self cancelButtonTitle:#"Done" otherButtonTitles:nil];
[alert show];
}
The methods:
[super touchesBegan:...];
[super touchesEnded:...];
[super touchesMoved:...];
are not implemented.
I added the AlertTable from another ViewController
AlertsTable *AlertTable = [[AlertsTable alloc] WithButton:sender withArray:self.PopTipViews];
[self.view addSubview:AlertTable.view];
I also implemented:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Set up the cell...
[[cell textLabel] setText:[AlertsItems objectAtIndex:indexPath.row]];
NSLog (#"%#",[AlertsItems objectAtIndex:indexPath.row]);
return cell;
}
Do you have any idea what the problem could be?
I'm not very experienced in Xcode and I'm really stuck.
Edit:
I know that it is not custom, but the link to the project can be found here (perhaps I'm overlooking something:
https://www.bilbu.be/BarConnect_v2.zip
The LoginViewController.xib is not properly linked (it is available in the en.lproj subfolder) so you may need to link first (I noticed too late and I had the file uploaded by a friend before - I cannot re-upload it myself unfortunately).
ViewController VC class calls the AlertsTable VC class. There is more in the project that I suppose you can ignore...
Note that the purpose of this project is only to serve as visual interface prototype. It is not meant to be the best optimized application (this is what other developers will do). If this doesn't work, I will use Photoshop to create the interfaces, but I guess that's not gonna be as convincing...

I successfully compiled your project. The problem is that you're going against the MVC pattern. The controller (AlertsTable) is inside of a view (CMPopTipView). I'd suggest you to rethink the hierarchy of the controllers and views. Hope this will help you.

Try changing
TableView.userInteractionEnabled = YES;
TableView.allowsSelection = YES;
TableView.allowsSelectionDuringEditing = YES;
to
self.TableView.userInteractionEnabled = YES;
self.TableView.allowsSelection = YES;
self.TableView.allowsSelectionDuringEditing = YES;
and are you allocating self.TableView? Something like...
self.TableView = [[UITableView alloc] init];//[[UITableView alloc] initWithStyle:UITableViewStylePlain];

Related

UIAccessibility is not selecting correct elements

I have several UIWindows in my app. Some UIWindows have very high window levels. i.e.
window.windowLevel = currentWindowLevel+1;
For some reason when turning on accessibility support, the system insists on reading out the accessibility labels of views located in the lower level window, even in cases where the views aren't even visible.
This minimal example exemplifies this behavior.
With accessibility support turned on, try to press the label in the red window. The system will read out the text from the underneath table view instead
#interface ViewController () <UITableViewDataSource>
#property (weak, nonatomic) IBOutlet UITableView *tableview;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tableview.dataSource = self;
[self.tableview registerClass:[UITableViewCell class] forCellReuseIdentifier:#"cell"];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
UIWindow *w = [[UIWindow alloc] initWithFrame:self.view.bounds];
w.windowLevel = self.view.window.windowLevel + 1;
w.backgroundColor = [UIColor redColor];
w.hidden = NO;
w.isAccessibilityElement = YES;
UILabel *l = [[UILabel alloc] init];
l.text = #"KUKUKUKUKUKUKUKLU";
[l sizeToFit];
l.frame = CGRectOffset(l.frame, 40, 100);
[w addSubview:l];
w.accessibilityLabel = #"Read this outloud instead";
static id window;
window = w;
});
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 100;
}
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
cell.textLabel.text = #"Test";
return cell;
}
#end
Solution is to set the attribute
Window.accessibilityViewIsModal = YES;

How to push new view from TableViewCell?

In my app I am trying to navigate to a new View from a TableViewCell, But i dont know how. Could you help guys? I am using Xcode 4.6. and .xib, no storyboard. I am very new to coding so please explain it as simple as possible! Here is what i have tried, please correct me:
- (void)viewDidLoad
{
tableData = [[NSArray alloc] initWithObjects:#"aaoversikt1", #"Paul", #"George", #"Ringo", nil];
[super viewDidLoad];
UILabel *nav_title1 = [[UILabel alloc] initWithFrame:CGRectMake(60, 10, 220, 25)];
nav_title1.font = [UIFont fontWithName:#"Arial-BoldMT" size:18];
nav_title1.textColor = [UIColor whiteColor];
nav_title1.adjustsFontSizeToFitWidth = NO;
nav_title1.textAlignment = NSTextAlignmentCenter;
nav_title1.text = #"Ålesund";
nav_title1.backgroundColor = [UIColor clearColor];
self.navigationItem.titleView = nav_title1;
}
#pragma mark - TableView Data Source methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section;
{
return [tableData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
UITableViewCell *cell = nil;
static NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [tableData objectAtIndex:indexPath.row];
return cell;
}
#pragma mark - TableView Delegate methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
AAOversiktViewController *aaoversikt1 = [[AAOversiktViewController alloc] initWithNibName:#"AAOversiktViewController" bundle:nil];
[self.navigationController pushViewController:aaoversikt1 animated:YES];
}
Thank You!
From first glance I would say that the problem lies within your [self.navigationController pushViewController] method. Have you initiated a navigation controller in your app either in the app delegate or root view controller?
If not i would recommend:
[self presentViewController:aaoversik1 animated:YES completion:NULL];
If you are wanting to push through the navigation stack so that you have a back button then I would look at implementing a UINaviationController.
Otherwise you can create a custom back button and use the same method in this post to present the root view controller (not totally recomended as using UINavigationController is much cleaner).
Let me know if this has been of any help, T

UITableView Segue

Im trying to make a small project. Could someone help me understand why the segue does not work?
#import "CarTableViewController.h"
#import "CarTableViewCell.h"
#import "CarDetailViewController.h"
#interface CarTableViewController ()
#end
#implementation CarTableViewController
#synthesize carMakes = _carMakes;
#synthesize carModels = _carModels;
#synthesize carImages = _carImages;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.carMakes = [[NSArray alloc]
initWithObjects:#"Chevy",
#"BMW",
#"Toyota",
#"Volvo",
#"Smart", nil];
self.carModels = [[NSArray alloc]
initWithObjects:#"Volt",
#"Mini",
#"Venza",
#"S60",
#"Fortwo", nil];
self.carImages = [[NSArray alloc]
initWithObjects:#"chevy_volt.jpg",
#"mini_clubman.jpg",
#"toyota_venza.jpg",
#"volvo_s60.jpg",
#"smart_fortwo.jpg", nil];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (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 _carModels.count;
}
#pragma mark - Table view data source
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"carTableCell";
CarTableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CarTableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
// Configure the cell...
cell.makeLabel.text = [self.carMakes
objectAtIndex: [indexPath row]];
cell.modelLabel.text = [self.carModels
objectAtIndex:[indexPath row]];
UIImage *carPhoto = [UIImage imageNamed:
[self.carImages objectAtIndex: [indexPath row]]];
cell.carImage.image = carPhoto;
return cell;
}
The code work´s fine, and loads a tableView, but I need to go to CarDetailViewControler and I´m using the following code, but it does not work.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"ShowCarDetails"])
{
CarDetailViewController *detailViewController =
[segue destinationViewController];
NSIndexPath *myIndexPath = [self.tableView
indexPathForSelectedRow];
detailViewController.carDetailModel = [[NSArray alloc]
initWithObjects: [self.carMakes
objectAtIndex:[myIndexPath row]],
[self.carModels objectAtIndex:[myIndexPath row]],
[self.carImages objectAtIndex:[myIndexPath row]],
nil];
}
}
In the storyboard did you use a cell prototype? If so, did you control-drag from the prototype to the destination viewcontroller and create the named segue?
The method you are using requires the segue to be defined completely in the storyboard, meaning the trigger for the segue is tied to the cell prototype.
You can manually trigger a segue using:
[self performSegueWithIdentifier:#"ShowCarDetails" sender:self];
in your:
tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath as an alternative.

longpress custom items UICollectionViewCell image change

How can I make a cell imageview to change after longpress gesture?
With this one when I click on a cell (longpress) the 4 customized items appear but when I select one of them the app crashes. (if you remove :(Cell*)cell and cell.imageView.image = [UIImage imageNamed:[NSString stringWithFormat:#"ICUbedRED.png"]]; it works...I mean the alertView appears but of course the image doesn't change).
- (void)longPress:(UILongPressGestureRecognizer *)recognizer {
if (recognizer.state == UIGestureRecognizerStateBegan) {
Cell *cell = (Cell *)recognizer.view;
[cell becomeFirstResponder];
UIMenuItem *highDep = [[UIMenuItem alloc] initWithTitle:#"High Dependency" action:#selector(hiDep:)];
UIMenuItem *lowDep = [[UIMenuItem alloc] initWithTitle:#"Low Dependency" action:#selector(lowDep:)];
UIMenuItem *booked = [[UIMenuItem alloc] initWithTitle:#"Booked" action:#selector(booked:)];
UIMenuItem *free = [[UIMenuItem alloc] initWithTitle:#"Free" action:#selector(free:)];
UIMenuController *menu = [UIMenuController sharedMenuController];
[menu setMenuItems:[NSArray arrayWithObjects:booked, highDep, lowDep, free, nil]];
[menu setTargetRect:cell.frame inView:cell.superview];
[menu setMenuVisible:YES animated:YES];
}
}
the voids are:
- (void)hiDep:(Cell*)cell
{
NSLog(#"Bed is HiDep");
cell.imageView.image = [UIImage imageNamed:[NSString stringWithFormat:#"ICUbedRED.png"]];
UIAlertView *testAlert = [[UIAlertView alloc] initWithTitle:#"This Bed is High Dependency"
message:#""
delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[testAlert show];
[testAlert release];
}
- (void)lowDep:(Cell*)cell
{.
cell.imageView.image = [UIImage imageNamed:[NSString stringWithFormat:#"ICUbedYELLOW.png"]];
..}
- (void)free:(Cell*)cell
{..
cell.imageView.image = [UIImage imageNamed:[NSString stringWithFormat:#"ICUbedGREEN.png"]];
.}
- (void)booked:(Cell*)cell
{..
cell.imageView.image = [UIImage imageNamed:[NSString stringWithFormat:#"ICUbedBLUE.png"]];
.}
and the cell building method is:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier = #"Cell";
Cell *cvc = (Cell *)[collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
int i = indexPath.row%[labelArray count];
number = i;
UILongPressGestureRecognizer *recognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPress:)];
[cvc addGestureRecognizer:recognizer];
cvc.imageView.image = [UIImage imageNamed:[NSString stringWithFormat:#"icubed.png"]];
cvc.label.text = [labelArray objectAtIndex:number];
return cvc;
}
#dottorfeelgood It is crashing for
cell.imageView.image = [UIImage imageNamed:[NSString stringWi......
because, the object retured as param to methods like
(void)lowDep:(Cell*)cell
is not of Class Cell, the retured param is of class UIMenuItem. because you are clicking on menuItems not Cell.
Instead of doing what you are doing now, you can use the MenuItems and corresponding actions on UICollectionCell solution provided by UICollectionView by default. You can check this tutorial here!
Just implement the 3 delegate methods and
// These methods provide support for copy/paste actions on cells.
// All three should be implemented if any are.
- (BOOL)collectionView:(UICollectionView *)collectionView shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath;
- (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender;
- (void)collectionView:(UICollectionView *)collectionView performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender;
and set your custom menuItems needed to the sharedMenuController in ViewdidLoad.
Hope this helps, excuse my bad sentence forming.

How to get indexPath in a tableview from a button action in a cell?

I have a tableview with two actions in it, for the first on i use the delegate didSelectRowAtIndexPath, for the second one i would like to use an action on a button on my cell to do something else. My problem is that i don't succeed to get the indexpath ? What is the best practice to do that.
If you have added the button to the cell as,
[cell.contentView addSubview:button];
then, you can get the index path as,
- (void)onButtonTapped:(UIButton *)button {
UITableViewCell *cell = (UITableViewCell *)button.superview.superview;
NSIndexPath *indexPath = [tableView indexPathForCell:cell];
// Go ahead
}
I'm using this solution -- getting index path of cell using points
CGPoint center= [sender center];
CGPoint rootViewPoint = [[sender superview] convertPoint:center toView:_tableView1];
NSIndexPath *indexPath = [_tableView1 indexPathForRowAtPoint:rootViewPoint];
NSLog(#"%#",indexPath);
Its work perfectly
here is the full code for a custom button:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
CustomCellFilter *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {cell = [[CustomCellFilter alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];}
//configure your cell here
cell.titleLabel.text = #"some title";
//add button
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];
resetButton.frame = CGRectMake(40, 10, 18, 18);
[resetButton addTarget:self action:#selector(onButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[resetButton setImage:[UIImage imageNamed:#"someimage.png"] forState:UIControlStateNormal];
[cell.contentView addSubview:myButton];
//afterwards return the cell
return cell;
- (void)onButtonTapped:(UIButton *)button {
UITableViewCell *cell = (UITableViewCell *)button.superview.superview;
NSIndexPath *indexPath = [filterTable indexPathForCell:cell];
NSLog(#"%#", indexPath);
//use indexPath here...
}
In case you are using a collection view, you can use Yogesh method, but change indexPathForRowAtPoint for indexPathForItemAtPoint like this:
CGPoint center= [sender center];
CGPoint rootViewPoint = [[sender superview] convertPoint:center toView:_tableView1];
NSIndexPath *indexPath = [_tableView1 indexPathForRowAtPoint:rootViewPoint];
NSLog(#"%#",indexPath);
In case that your button is moved or Apple changes the view hierarchy for accessory views, this method goes up the chain to look for a UITableViewCell:
- (void)tapAccessoryButton:(UIButton *)sender {
UIView *parentView = sender.superview;
// the loop should take care of any changes in the view heirarchy, whether from
// changes we make or apple makes.
while (![parentView.class isSubclassOfClass:UITableViewCell.class])
parentView = parentView.superview;
if ([parentView.class isSubclassOfClass:UITableViewCell.class]) {
UITableViewCell *cell = (UITableViewCell *) parentView;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
[self tableView:self.tableView accessoryButtonTappedForRowWithIndexPath:indexPath];
}
}

Resources