I have a ViewController wich have a UItableView.
Inside every cell in this TableView I have a subview.
In the first row of my TableView I have a subview that contains 2 buttons.
I want that when one of those buttons are pressed, my UINavigationController pushes my secondViewController on the screen.
But nothing happens, I don't get any errors, just don't happen!
I already try everything I now, but nothing seems to work.
Here is my code at my AppDelegate.m
firstViewController * firstView = [firstViewController new];
UINavigationController * navViewController = [[UINavigationController alloc]initWithRootViewController:firstView];
self.window.rootViewController = navViewController;
In my firstViewController I have my TableView:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString * CellIdentifier = #"Cell";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (indexPath.section == 0 && indexPath.row == 0) {
[cell.contentView addSubview:_actionBar];
}
else {
for (UIView * view in cell.contentView.subviews) {
[view removeFromSuperview];
}
_feed = [[Y_feedViewController sharedFeed]getViewWithThisInfo:[_arrayOfFeeds objectAtIndex:indexPath.section]];
[cell.contentView addSubview:_feed];
}
return cell;
}
So, the Buttons are in my _actionBar (that I add as a subview in my first row), and when I press the Button01 I want to call my secondViewController
Man, I already try everything, but can't work with this.
I already try to call the pushViewController: from my _actionBar, my TableViewController, my firstViewController, etc.
Thanks.
It's not clear how you are assigning an action to the buttons in _ActionBar. I think it would be easier and cleaner to use two different cell types, one of which has the buttons in it (rather than adding a subview in code). Just dequeue the one you want based on the indexPath. When you dequeue the one for the first row, add the action and target for your buttons (with the target being the view controller).
Related
I am new to IOS and i was just working on UITableView. I want to populate data in table view from two different View Controllers. I want to update cell.textLabel.text from View Controller say viewController1 and cell.detailTextLabel.text from another View Controller say viewController2.
I have a barbutton at the top right of the tableView and clicking on which it navigates to View Controller A. I have a text label in View Controller A and it returns what ever user has entered to tableView.
When i click the cell, it navigates to View Controller B. I also have a text label in View Controller B.
Here is my tableView datasource method
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
Names *namesToDisplay = [self.lists objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = namesToDisplay.firstName;
return cell;
}
where Names is a model class of NSObject and lists is an NSArray in tableView.
It works fine if I update cell.textlabel.text and cell.detailtextlable.text from a single View Controller either View Controller1 or View Controller2.
I can get data from viewController2 but where should I have cell.detailTextLabel.text ?
coding conventions... http://en.wikipedia.org/wiki/Naming_convention_%28programming%29#Java is a good orientation.
It seems like simple parameter handling. You can share the information between the views in the init process.
i.e.
// your details view (vc2) header
#class Names;
#interface MyDetailsViewController
{
Names *names;
// some variable declaration here
}
// maybe some properties...
- (id)initWithObject:(Names *)p_names;
// ...
#end
...
// your details view (vc2) main
- (id)initWithObject:(Names *)p_names
{
if ((self = [super init]))
{
names = p_names; // so you have the data when the tableView is loading
}
}
...
// your main view (vc1)
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Names *namesToDisplay = [self.lists objectAtIndex:indexPath.row];
MyDetailsViewController *viewController2 = [[MyDetailsViewController alloc] initWithObject:namesToDisplay];
[self.navigationController pushViewController:viewController2 animated:YES];
}
if there are further problems, please give some more information where exactly ;)
UITableViewCells get emptied on scroll (Objective-C)
I am having a problem with UITableViewCells getting emptied as soon I a start to scroll within the table view.
I already had a look at Cells become empty after scrolling. (Xcode) - however the problem still persists.
1) I have a popover view controller, which presents a way to log into some administration. Upon successful login (which hasn’t been implemented yet, the LOGIN button simply takes one straight to a test tableView - which should be fed from some external database later on).
2) Upon successful login, the login view inside the popover gets removed and a custom UITableViewController comes into play with its own XIB.
3) This UITableViewController uses a custom UITableViewCell - since prototype cells are not possible within this configuration.
It all works to the point where I scroll the table - and all the cells get emptied for some reason.
Here is the code run down (I leave out the obvious, eg properties and table section, etc setups):
1) customPopUpViewController(XIB ,.h, .m):
- (IBAction)loginButtonPressed:(UIButton *)sender {
UITableViewController *libraryTableViewController = [[LibraryAdminTableViewController alloc]initWithNibName:#"LibraryAdminTableViewController" bundle:nil];
libraryTableViewController.view.frame = CGRectMake(0, 179, libraryTableViewController.view.frame.size.width, libraryTableViewController.view.frame.size.height);
[self.view addSubview:libraryTableViewController.view];
}
2) LibraryAdminTableViewController (XIB ,.h, .m):
- (void)viewDidLoad {
[super viewDidLoad];
self.LibraryAdminTable.delegate = self;
self.LibraryAdminTable.dataSource = self;
self.tblContentList = [[NSMutableArray alloc]init];
self.tblContentList = [NSMutableArray arrayWithObjects:#"Sync Pack 1",#"Sync Pack 2",#"Sync Pack 3", nil];
[self.LibraryAdminTable registerNib:[UINib nibWithNibName:#"LibraryAdminTableViewCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:#"LibraryAdminCell"];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
LibraryAdminTableViewCell *cell = [self.LibraryAdminTable dequeueReusableCellWithIdentifier:#"LibraryAdminCell" forIndexPath:indexPath];
NSString* trackList = [self.tblContentList objectAtIndex:indexPath.row];
cell.cellLabel.text = trackList;
return cell;
}
3) LibraryAdminTableViewCell (XIB ,.h, .m) - I gave the Identifier in the Attributes Inspector “LibraryAdminCell”:
#property (strong, nonatomic) IBOutlet UILabel *cellLabel;
What am I missing?
It is solved. According to this thread I had to get a strong reference to the custom UITableViewController via a property in the popup controller since the ViewController (being the DataSource for the tableView) would not be retained in memory.
This is happening because you are not creating a new cell, when tableview will try to dequeue a cell, and it does not get the cell, then it should create the cell to use but you are not creating any cell, so it is returning nil.Try the code below
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
LibraryAdminTableViewCell *cell = (LibraryAdminTableViewCell*)[self.LibraryAdminTable dequeueReusableCellWithIdentifier:#"LibraryAdminCell"
forIndexPath:indexPath];
if (cell == nil)
{
cell = [[LibraryAdminTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"LibraryAdminCell"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
NSString* trackList = [self.tblContentList objectAtIndex:indexPath.row];
cell.cellLabel.text = trackList;
return cell;
}
In a VC I have a tableView with custom Cell "ChartListCell". When the user is on any particular cell I want to open a view with 2 buttons in it on top of the cell and let user click on any button and appropriate action be taken for that cell. What would be the best way to implement this feature ? I am stuck at :-
Event to find cell/row is selected.
Place the view at the cells' position - so it stays on top of the cell.
Create the view with 2 btns - would be better to create it programmatically so events can be mentioned in the same VC only or to create a xib would be better option ?
Hide the view again when selection is lost.
UPDATE :-
So I tap the cell, the view (like below with 2 buttons) appears. If I scroll the table, the view stays on the cell. Once I tap an option on the new view , or tap on another cell or somewhere outside it disappears.
UPDATE :-
I created a xib file and in didSelectRowAtIndexPath am trying to show the view, but it's not appearing.
// Get the SELECTED CELL
ChartListCell *cell = (ChartListCell*)[tableView cellForRowAtIndexPath:indexPath];
NSLog(#"ABOUT TO SHOW VOV");
NSArray *visitorOptView = [[NSBundle mainBundle] loadNibNamed:#"VisitorsOptionsView" owner:self options:Nil];
VisitorsOptionsView *vov = [visitorOptView objectAtIndex:0];
vov.frame = cell.frame;
[self.view addSubview:vov];
[self.view bringSubviewToFront:vov];
Nothing appears. Where am I going wrong ? To give the same location as of the cell, I tried vov.frame = cell.frame , but I think I may be wrong at that step. What else should be at that place ???
What would be the best methods to implement the above ? Can you please help me guide out. Any help is highly appreciated.
Below image shows what I am looking to meet up the design :-
I made this demo project for you:http://goo.gl/Y6GFmj , you can download it
You can add the view into your table cell instead of your view. You need to subclass your table view cell and add a property to hold the overlay view.
#interface MyTableViewCell : UITableViewCell
#property (weak, nonatomic) UIView * overlayView;
#end
Note that the overlay view should be a weak property, because the cell's view will have the strong reference to it, just like an IBOutlet.
You need to add another property in your table view controller to hold the last selected index path, so that when you select a new row, you can remove the overlay view in the old one.
#property (strong, nonatomic) NSIndexPath * lastSelectedRow;
Use the following function to remove the overlay view from a cell
- (void)removeViewInCellOfIndexPath:(NSIndexPath *)indexPath
{
if (!indexPath)
return;
MyTableViewCell * cell = (MyTableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath];
if (cell.overlayView)
{
[cell.overlayView removeFromSuperview];
}
}
Now you can deal with the selection:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// deselecte the row
[tableView deselectRowAtIndexPath:indexPath animated:NO];
// remove the overlay view from the last selected row
[self removeViewInCellOfIndexPath:self.lastSelectedRow];
// add overlay view to this row
MyTableViewCell * cell = (MyTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
// note the origin of the frame is (0, 0) since you are adding itto the cell instead of the table view
UIView * view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, cell.frame.size.width, cell.frame.size.height)];
view.backgroundColor = [UIColor greenColor];
[cell.contentView addSubview:view];
// remember this view and this indexpath
cell.overlayView = view;
self.lastSelectedRow = indexPath;
}
I had done something similar to this, What I did was while creating my custom cell I had placed another view at the bottom which contained the two buttons, make the two buttons as IBOutlets of their classes.
When I load it in my table view with the usual method in CellForROwAtIndexpath I defined as following...
- (UITableViewCell *)couchTableSource:(CBLUITableSource*)source
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellid=#"Cell";
CustomTableCell* cell=(CustomTableCell*)[_Mytableview dequeueReusableCellWithIdentifier:cellid];
if(cell==nil)
{
NSArray *nib=[[NSBundle mainBundle] loadNibNamed:#"CustomTableCell" owner:self options:nil];
cell=[nib objectAtIndex:0];
}
[cell.firstButton addTarget:self action:#selector(firstButtonClicked:event:) forControlEvents:UIControlEventTouchUpInside];
[cell.secondButton addTarget:self action:#selector(SecondButtonClicked:event:) forControlEvents:UIControlEventTouchUpInside];
}
I maintained a global integer flag as SelectedIndex and used it as follows
In didSelectRowAtIndexPath I have done something Like this..
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(selectedIndex == indexPath.row)
{
selectedIndex = -1;
[_Mytableview reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
return;
}
//First we check if a cell is already expanded.
//If it is we want to minimize make sure it is reloaded to minimize it back
if(selectedIndex >= 0)
{
NSIndexPath *previousPath = [NSIndexPath indexPathForRow:selectedIndex inSection:0];
selectedIndex = indexPath.row;
[_Mytableview reloadRowsAtIndexPaths:[NSArray arrayWithObject:previousPath] withRowAnimation:UITableViewRowAnimationFade];
}
//Finally set the selected index to the new selection and reload it to expand
selectedIndex = indexPath.row;
[_Mytableview reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
also and the most important step in heightForRowAtIndexPath
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row == selectedIndex)
{
return (return the actual size of the cell, Including the view with two buttons);
}
else
{
return (return the size of cell -(the size of view containing the two buttons));
}
}
In viewWillAppear make Sure to assign this so that the cell would be normal whenever the is presented
-(void)viewWillAppear:(BOOL)animated
{
selectedIndex=-1;
[myTableView reloadData];
}
I've got a UIPopoverController created programmatically which pops up with the content from a UIViewController from a .xib. The UIViewController contains a (grouped) UITableView and a UITableViewCell "prototype".
When The popover pops up, the cell prototype is duplicated for all cells needed. The number of cells exceeds the size of the popover, so I can scroll through all cells.
When the popover pops up, everything looks nice, the cell labels are all left aligned. As soon as I touch the tableview to scroll, all cell labels suddenly align to center. When I scroll the cells outside and back in, the are left aligned again. After I scrolled all cells outside for once, they keep left aligned for the rest of their lifetime. I have no idea what is causing this... there is nothing in my code that alters the alignment of the cells. Here's some code:
UIViewController *editPopoverView = [[[ComponentViewEmptyEditPopover alloc] initWithNibName:#"ComponentViewEmptyEditPopover" bundle:nil] autorelease];
UIPopoverController* aPopover = [[UIPopoverController alloc] initWithContentViewController:editPopoverView];
aPopover.delegate = self;
[aPopover presentPopoverFromRect:sender.frame inView:self permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
From the popover viewcontroller
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *theCell = nil;
switch (indexPath.section)
{
case 0:
theCell = [tableView dequeueReusableCellWithIdentifier:#"typeCell"];
if (theCell == nil)
{
NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:self.typeCell];
theCell = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData];
}
switch (indexPath.row)
{
case 0:
[theCell.textLabel setText:#"Empty"];
break;
//
}
break;
}
return theCell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 1)
return 420;
return 44;
}
Any ideas why this is happening? I guess this is somehow related to cell reuse.
Update: Like I already guessed, it has to to with the reusing. When I do
theCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:#"theCell"];
everything works fine. However, I want to be able to change the design of the cell through interface builder...
Update 2: If I comment out the dequeueReusableCellWithIdentifier line, all cells will go back to center alignment after they scroll in.
I was just playing around with IOS and I hit a problem and it seems so simple that I can't believe it's not working
I have a table list
I have set up all the delegate so that it displays information from a plist
that works
however when I switched to my custom view for the internal layout, I get the default text of the view but not the text form the plist
Here is some code of the table view controller:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"DefaultCell"];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"DefaultCell"];
}
EmergencyContactItemConrtroller *genericViewController = [[EmergencyContactItemConrtroller alloc] initWithNibName:#"EmergencyContactItemConrtroller" bundle:nil];
[genericViewController setInitialParametersWithTitle:[[emergencyArray objectAtIndex:indexPath.row]objectForKey:#"Title"]
withCatption:[[emergencyArray objectAtIndex:indexPath.row]objectForKey:#"Caption"]
withNumber:[[emergencyArray objectAtIndex:indexPath.row]objectForKey:#"Number"]
withOtherInfo:nil];
[cell.contentView addSubview:genericViewController.view];
return cell;
}
and here is the code of setInitialParametersWithTitle in the cell view controller.
-(void) setInitialParametersWithTitle:(NSString *)title
withCatption:(NSString *)caption
withNumber:(NSString *)number
withOtherInfo:(NSDictionary *)otherInfo{
self.titleLable.text = title;
self.captionLable.text = caption;
[self.numberButton setTitle:number forState:UIControlStateNormal];
}
I checked that the xib IBOutlet are linked correctly.
when I try to debug I get he right values send to the function, how ever when I printout self.titleLable.text before assigning a value to it, there is no value in it.
Any Ideas ?
Jason
EmergencyContactItemConrtroller is UIViewController class?
All IBOutlets will initialized after
[cell.contentView addSubview:genericViewController.view]
is done; Then you should change them
Try to reload your table view in -(void)viewwillappear()
Try this, inside if(cell==nil),
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"DefaultCell"];
cell.contentView = [[UIView alloc]init];
}
Then you can add subView above cell's contentView