I have a viewcontroller.xib which contains View, buttons,toolbarbutton, text box and a tableview. When I load the initial screen comes without table view which is fine. Now when I click on a toolbarbutton say, viewtable, I want the view to move to tableview. I have filled my tableview data with some default objects like this:
- (void)viewDidLoad
{
tableData = [[NSArray alloc] initWithObjects:#"object1",#"object2",#"object3",#"object4", nil];
[super viewDidLoad];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [tableData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:#"My Cell"];
if(cell==nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"My Cell"];
}
cell.textLabel.text=[tableData objectAtIndex:indexPath.row];
return cell;
}
So when I click on toolbar view button it should show tableview with toolbar button which also has a back button so when I click on that it should hide the table view and show the initial view. Is it possible to do all this in single xib? I can achieve the result if I create another xib and simply transfer control over to that xib but I wanted to know if its possible do this without creating a second xib file. And also for navigation I can use navigation controller but I want to check and see if its possible to use toolbar to transfer the control. Thanks.
First check if your table view is inside your view, if not put it inside and set delegate of datasource to file owner, then in your view table method write this code
-(void)viewTable
{
self.tableView.hidden = NO;
self.viewToolbar.hidden=YES;
}
On your back button code in toolbar write
-(void)goback
{
self.tableView.hidden = YES;
self.viewToolbar.hidden=NO;
}
If you don't need animation then you can do the following
Get a handle of tableView in your interface like this:
#property(nonatomic,assign)IBOutlet UITableView *tableView;
Hide your table view in initially ( like in viewDidLoad method )
-(void)viewDidLoad
{
[super viewDidLoad];
self.tableView.hidden = YES;
}
Then in the method called by your toolbar's button do the following
-(void)on_click_toolbar_button
{
self.tableView.hidden = !self.tableView.hidden;
//This will keep toggling the table view from hidden to shown & vice-versa.
}
you could use the hidden property to achieve that. Put these in the appropriate ibaction methods.
_tableView.hidden = Yes;
_tableView.hidden = No;
I'd highly recommend to do this in two separate XIBs. The first should contain a UIViewController (your initial view) and the second a UITableViewController (your table view) class. Both should be handled by a UINavigationController - don't fight the API and try your own hacks if it's not necessary. The mentioned controller classes give you everything you need out of the box.
Well this is not recommended but you can do this by removing and adding tableview..
Related
1) I have a simple table view hosted by view controller and cell hosted by custom UITableViewCell class. A button on my cell drops down a menu (a simple table view controller loading from the non-host 'out of the picture' class using FPPopoverMenu).
2) The problem is I want to update my button background image on dropdown menu row selection which involves my 'out of the picture dropdown menu tableview class' and my 'custom table view cell class' totally deserting the host of my custom UITableViewCell.
3) I tried using NSNotification like, I successfully did for a simple scenario involving only host-class and dropdown menu class but now its the custom tableview cell (which is a repeating entity) and dropdown class I want to communicate.. Please help. I set up NSNotification but background image stays the same, means notification doesn't reach/doesn't reach in time.
4) Apparently I need 10 reputation to post image (:-[) so here's the link:
As shown by the image, I have fired notification on dropdown's didSelectRow, when Hide is pressed, background should change otherwise, if show is pressed it should be green as shown..as i did before but this doesn't do anything for me. Any help will be greatly appreciated. thank you in advance!
To achieve this you can use blocks.
You need to add
#property (nonatomic, copy) void (^didSelectAction)(NSIndexPath *indexPath);
to view controller which is shown in popover.
than in tableView: didSelectRowAtIndexPath: call this block
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (self.didSelectAction)
self.didSelectAction(indexPath);
}
So when you create a popover you should provide additional handler.
Something like this
Add new action to your button
- (UITableViewCell *) tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CustomCell"];
[[cell button] addTarget:self action:#selector(showPopoverFromButton:) forControlEvents:UIControlEventTouchUpInside];
}
- (void) showPopoverFromButton:(UIButton *)sender {
//Your table view which is shown in popover
UITableViewController *controller = [[UITableViewController alloc] init];
[controller setDidSelectAction:^{
[sender setBackgroundColor:[UIColor redColor]];
}];
FPPopoverMenu *popover = [[FPPopoverController alloc] initWithViewController:controller];
[popover show];
}
I have created a tier of three UITableViews using Storyboard and am able to move from the first to the second and then to the third. I now want to create a fourth UITableView programmatically. By selecting a Cell in the third UITableView a fourth tier UITableView must be created and displayed so that I can populate it with data. Please help. Thanks very much. Herewith included is the portion of the code that I want to execute :
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.textLabel.text = [self.grapes objectAtIndex:indexPath.row];
if ([cell.textLabel.text isEqual: #"Grape variety"]) {
//create the navigation controller and add the controllers view
navigationController = [[UINavigationController alloc] init];
[self.window addSubview:[self.navigationController view]];
//check if the display viewcontroller exists, otherwise create it
if(self.displayViewController == nil) {
ViewController *inputView = [[ViewController alloc] init];
self.displayViewController = inputView;
}
//push the display viewcontroller into the navigation view controller stack
[self.navigationController pushViewController:self.displayViewController animated:
}
The "-(void)tableView ... is from the TableView created using Storyboard and the last portion of the code is the TableView I want to create programmatically.
If I excecute the code the newly created TableView corrupts the one created in the Storyboard and it doesn't display the one I want to create programmatically, somehow one must be able to change the priority of the display and get the latest created one to be the one that is active
I would use a drill down approach where the segue on the storyboard effectively loops back on itself (see image below):
You could then provide an abstracted datasource and delegate implementation to make the view controller as light of logic as possible. Eg
#implementation ArrayDataSource
- (id)itemAtIndexPath:(NSIndexPath*)indexPath {
return items[(NSUInteger)indexPath.row];
}
- (NSInteger)tableView:(UITableView*)tableView
numberOfRowsInSection:(NSInteger)section {
return items.count;
}
- (UITableViewCell*)tableView:(UITableView*)tableView
cellForRowAtIndexPath:(NSIndexPath*)indexPath {
id cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier
forIndexPath:indexPath];
id item = [self itemAtIndexPath:indexPath];
configureCellBlock(cell,item);
return cell;
}
#end
You could then configure it according to which tableview you are using by keeping a track of where you are:
void (^configureCell)(PhotoCell*, Photo*) = ^(PhotoCell* cell, Photo* photo) {
cell.label.text = photo.name;
};
photosArrayDataSource = [[ArrayDataSource alloc] initWithItems:photos
cellIdentifier:PhotoCellIdentifier
configureCellBlock:configureCell];
self.tableView.dataSource = photosArrayDataSource;
I change the value of 2 UILabels in my "viewDidLoad" method, but I need the view to refresh after that in order to display the values. As it currently stands, the UILabels display the value of the previously selected cell. I need to do the refresh right after I change the labels' values. The "setNeedsDisplay" method is not doing the job.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
_nameLabel.text = _selectedLocation.name;
_addressLabel.text = _selectedLocation.address;
[self.view setNeedsDisplay];
}
Based on your comments, I think you are trying to do something like:
- (void)updateLabelTexts {
_nameLabel.text = _selectedLocation.name;
_addressLabel.text = _selectedLocation.address;
}
and wherever you are changing the _selectedLocation values:
//Just an example
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
_selectedLocation = _yourLocationsArray[indexPath.row];
//now you call your update method
[self updateLabelTexts];
}
The point is that you have to call [self updateLabelTexts]; just after you update the values.
A very stupid bug. Turns out when I made the segue to transition into the next view, I actually dragged it from a physical cell on to the destination controller. However, I should've simply connected the sending uiview controller to the destination viewcontroller with the segue, and then manually handled the transition. That fixed it, so there's no need to "refresh or reload" the UIView as I was trying to do.
I've created a header for the first section in my UITableView. The Header is created by a view in .nib file. I've connected the button to the Views owner which is a class called HeaderSection which is a subclass of UITableViewHeaderFooterView.
Here's the code for what should happen when the button is clicked.
#import "HeaderSection.h"
#implementation HeaderSection
- (IBAction)touchButton1:(UIButton *)sender {
NSLog(#"Touch button 1 tapped!");
}
#end
And here's a screen shot of things overall.
The problem is when I tap on the button, it doesn't detect the tap, instead the cell below the button detects the tap and the code runs accordingly (brings on a new UIViewController).
How can I make it detect the top button?
Here's more code from my main ViewController.
- (void)viewDidLoad
{
[super viewDidLoad];
UINib *sectionHeaderNib = [UINib nibWithNibName:#"headerNib" bundle:nil];
NSString *SectionHeaderViewIdentifier = #"sectionHeaderIndentifier";
[self.tableView registerNib:sectionHeaderNib forHeaderFooterViewReuseIdentifier:SectionHeaderViewIdentifier];
self.iconSets = [IconSet iconSets];
self.tableView.allowsSelectionDuringEditing = YES;
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:#selector(longPressGestureRecognized:)];
[self.tableView addGestureRecognizer:longPress];
self.filteredIcons = [NSMutableArray array];
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 60.0f;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
NSString *SectionHeaderViewIdentifier = #"sectionHeaderIndentifier";
HeaderSection *sectionHeaderView = [self.tableView dequeueReusableHeaderFooterViewWithIdentifier:SectionHeaderViewIdentifier];
return sectionHeaderView;
}
And here's a screen shot of the view in the .xib (I've made the underlying view dark grey to stand out).
One problem you have is that in the .xib file, the top-level object must be set, in the idendity inspector, to be the custom UIView subclass that it is, or nothing will work.
However, it looks like other things are going on. The gray from the tableview cell underneath shouldn't be peaking out on the right of the footer. Is this being added in the tableView:viewForHeaderInSection: method of the UITableViewDataSource? It can adjust the headerView's frame there to be the width of the tableView. Depending on what the button is going to do, it might also need a reference to the view controller.
If the search bar and buttons are going to stay on top always, they don't really need to be a header. On that .xib you have, just put a tableview underneath the button bar. Create a ViewController with that file as the .xib, then connect that tableView's dataSource and delegate to that View Controller. You may need to create a ViewController with built-in xib to do this automatically, in or out of storyboards.
Freestanding xibs are discouraged but I think they're perfect for this case, tableView/collectionView reusable views. But if its on top of the table, not in it, it should be part of the view controller that contains the table.
I have a tableview controller with navigation bar, it is used for user profile screen. tableview has 10 custom cells containing label,textfields and textview and navigation bar buttons are use for enabling/disabling the editing of tableviewcell contents. A user can load this user profile screen from any controller in the app with a button on that that view controller. what i want to do is, when a user selects to open this user profile screen(tableview Controller) from anywhere, it should appear only viewing mode; its cell having textfields and Textviews should not be editable. However when user navigates through settings screen of app and goes to user profile screen, its cells could be enable or disabled for editing. any suggestions for this ??
try this:
Part 1. Preparing your UITableViewController class
in the .h:
add... #property (nonatomic, assign) BOOL enableCellSelection;
.
in the .m
in the -initWithStyle: do...
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
enableCellSelection = YES;
}
return self;
}
in the -cellForRowAtIndexPath: do...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//your normal cell handling code
[cell setUserInteractionEnabled:(enableCellSelection ? UITableViewCellSelectionStyleBlue : UITableViewCellSelectionStyleNone)];
return cell;
}
Part 2. Showing your UITableViewController class
From any method...
//alloc/init normally
MyTableViewController *tvcObj = [[MyTableViewController alloc] init];
//explicitly disable the cell selection ability
tvcObj.enableCellSelection = NO;
//display the tableView
[self.navigationController pushViewController:tvcObj animated:YES];
Basically, we create a property that we set before showing the tableView and when the table loads, it will read this property and appropriately set the interaction ability on the entire cell.
this is the best I could think of