I'm trying to populate the menu in ECSlidingViewController(a UITableVIEW) using the code below, but when I run the app the menu, or uitableview, is blank and not populated with the 3 MenuItems; Important, Invitation, and Agenda. I suspect the problem lies within didSelectRowAtIndexPath, but I'm not sure. Any help with this would be much appreciated. Thank you.
#import "MenuViewController.h"
#interface MenuViewController ()
#property (nonatomic, strong) NSArray *menuItems;
#end
#implementation MenuViewController
#synthesize menuItems;
- (void)awakeFromNib
{
self.menuItems = [NSArray arrayWithObjects:#"Important", #"Invitation", #"Agenda", nil];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self.slidingViewController setAnchorRightRevealAmount:280.0f];
self.slidingViewController.underLeftWidthLayout = ECFullWidth;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)sectionIndex
{
return self.menuItems.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"MenuItemCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = [self.menuItems objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier = [NSString stringWithFormat:#"%#", [self.menuItems objectAtIndex:indexPath.row]];
UIViewController *newTopViewController = [self.storyboard instantiateViewControllerWithIdentifier:identifier];
[self.slidingViewController anchorTopViewOffScreenTo:ECRight animations:nil onComplete:^{
CGRect frame = self.slidingViewController.topViewController.view.frame;
self.slidingViewController.topViewController = newTopViewController;
self.slidingViewController.topViewController.view.frame = frame;
[self.slidingViewController resetTopView];
}];
}
1) Be sure to connect datasource and delegate outlets in IB, and
2) Is MenuViewController a subclass of UITableViewController? If not, then I think you're going to need to load the table data yourself someplace. Try this:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.tableView reloadData]; // need to have an outlet named this
}
If you don't have an outlet setup called tableView, pointing to the table view, create one in IB.
I suspect that your menuItems array is empty. Try populating it in viewDidLoad.
You may want to take a look at this for a discussion of awakeFromNib, viewDidLoad, initWithNibName.
Related
I am trying to use ECSlidingViewController which is available on github:
https://github.com/edgecase/ECSlidingViewController
Anyway I was wondering how to push data from the menu view controller to the sample table view controller because there is no segue. The navigation controller gets instantiated via storybaord but I see no way to push any data from view to another.
I tried now with delegates but it seems my delegate does not fire for some reason I dont know. The TableView stays empty. What did I miss?
Please see code below:
//MenuviewController.h
#import <UIKit/UIKit.h>
#import "ECSlidingViewController.h"
#protocol TableData <NSObject>
- (void) someData:(NSString*)data;
#end
#interface MenuViewController : UIViewController <UITableViewDataSource, UITabBarControllerDelegate>{
__unsafe_unretained id <TableData> delegate;
}
#property (nonatomic,assign) id <TableData> delegate;
#end
//MenuViewController.m
#import "MenuViewController.h"
#interface MenuViewController()
#property (nonatomic, strong) NSArray *menuItems;
#end
#implementation MenuViewController
#synthesize menuItems, delegate;
- (void)awakeFromNib
{
self.menuItems = [NSArray arrayWithObjects:#"First", #"Second", #"Third", #"Navigation", nil];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self.slidingViewController setAnchorRightRevealAmount:280.0f];
self.slidingViewController.underLeftWidthLayout = ECFullWidth;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)sectionIndex
{
return self.menuItems.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"MenuItemCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = [self.menuItems objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier = [NSString stringWithFormat:#"%#Top", [self.menuItems objectAtIndex:indexPath.row]];
UIViewController *newTopViewController = [self.storyboard instantiateViewControllerWithIdentifier:identifier];
if ([delegate respondsToSelector:#selector(someData:)]) {
[delegate someData:#"Hello World"];
}
[self.slidingViewController anchorTopViewOffScreenTo:ECRight animations:nil onComplete:^{
CGRect frame = self.slidingViewController.topViewController.view.frame;
self.slidingViewController.topViewController = newTopViewController;
self.slidingViewController.topViewController.view.frame = frame;
[self.slidingViewController resetTopView];
}];
}
#end
//SampleTableViewController.h
#import <UIKit/UIKit.h>
#import "ECSlidingViewController.h"
#import "MenuViewController.h"
#interface SampleTableViewController : UITableViewController <UITableViewDataSource, UITabBarControllerDelegate, TableData>
- (IBAction)revealMenu:(id)sender;
#end
//SampleTableViewController.m
#import "SampleTableViewController.h"
#interface SampleTableViewController()
#property (nonatomic, strong) NSArray *sampleItems;
#end
#implementation SampleTableViewController
#synthesize sampleItems;
- (void)awakeFromNib
{
//self.sampleItems = [NSArray arrayWithObjects:#"One", #"Two", #"Three", nil];
}
- (void) someData:(NSString *)data{
sampleItems = [NSArray arrayWithContentsOfFile:data];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)sectionIndex
{
return self.sampleItems.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"SampleCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = [self.sampleItems objectAtIndex:indexPath.row];
return cell;
}
- (IBAction)revealMenu:(id)sender
{
[self.slidingViewController anchorTopViewTo:ECRight];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return YES;
}
#end
I would suggest using a delegate. Here is an example: Delegate example
I finally found out.
Here is an example.
UINavigationController *navigationController = [self.storyboard instantiateViewControllerWithIdentifier:identifier];
MBFancyViewController *viewController = navigationController.viewControllers[0];
//or alternative
MBFancyViewController *viewController = (MBFancyViewController *)navigationController.topViewController;
// setup "inner" view controller
viewController.foo = bar;
[self presentViewController:navigationController animated:YES completion:nil];
I would like to make rounded corners for the first and last cell of UITableView. I have seen from this postCustom Rounded corners that you can use custom cells in a xib file, set their unique identifiers like: #"beginCell", #"middleCell", #"endCell". I do not want to use custom cells. Is there any other way to do this?
For example:
if (cell.count == 0 or cell.count == last)
{
cell.layer.cornerRadius = 10;
}
Something like this. But there is no property called count. Is there any other property?
EDITED:
ViewController.m
#import "ViewController.h"
#import <QuartzCore/QuartzCore.h>
#import "SecondViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize tableItems,images;
- (void)viewDidLoad
{
[super viewDidLoad];
tableItems = [[NSArray alloc] initWithObjects:#"Item1",#"Item2",#"Item3",nil];
images = [[NSArray alloc] initWithObjects:[UIImage imageNamed:#"clock.png"],[UIImage imageNamed:#"eye.png"],[UIImage imageNamed:#"target.png"],nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Required Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return tableItems.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//Step 1:Check whether if we can reuse a cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
//If there are no new cells to reuse,create a new one
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:#"cell"];
UIView *v = [[UIView alloc] init];
v.backgroundColor = [UIColor redColor];
cell.selectedBackgroundView = v;
//changing the radius of the corners
//cell.layer.cornerRadius = 10;
}
//Set the image in the row
cell.imageView.image = [images objectAtIndex:indexPath.row];
//Step 3: Set the cell text content
cell.textLabel.text = [tableItems objectAtIndex:indexPath.row];
//Step 4: Return the row
return cell;
}
#pragma mark - Optional Methods
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
cell.backgroundColor = [ UIColor greenColor];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
NSString *selectedRow = [tableItems objectAtIndex:indexPath.row];
secondViewController.selectedRow = selectedRow;
//[self.navigationController pushViewController:secondViewController animated:YES];
[self presentViewController:secondViewController animated:YES completion:nil];
[secondViewController printRowNumber:indexPath.row];
}
- (id)initWithFrame:(CGRect)frame style:(UITableViewStyle)style{
self = [super initWithFrame:frame style:style];
return self;
}
#end
Just change your UITableView initialization style to Grouped like that:
yourTableViewController = [[UITableViewController alloc] initWithStyle:UITableViewStyleGrouped];
This will make your first cell rounded from top and last cell rounded from bottom.
EDIT in case of not using UITableViewController initializer:
#interface YourViewController
#property (strong, nonatomic) UITableView *tableView;
#end
#implementation YourViewController
- (id)initWithFrame:(CGRect)frame
{
if (self = [super init])
{
...
tableView = [[UITableView alloc] initWithFrame:frame style:UITableViewStyleGrouped];
...
[self.view addSubview:tableView];
}
return self;
}
#end
Assuming you're putting this code in tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath, you can do it like this:
if (indexPath.row == 0 || indexPath.row == ([indexPath length]-1))
{
cell.layer.cornerRadius = 10;
}
I have two UITableView, each one has a different delegate in the same UIViewController.
I'm trying to call control in another delegate, but it failed.
Brief:
mainViewController contains UITableView (with UITableViewDelegate and UITableViewDataSource) + UIImageView.
secondaryTable contains UITableView (with UITableViewDelegate and UITableViewDataSource).
I want to call UIImageView from secondaryTable.
In .h
#interface secondaryTable : UIViewController <UITableViewDataSource,UITableViewDelegate>
#end
#interface mainViewController : UIViewController <UITableViewDataSource,UITableViewDelegate> {
#property (nonatomic,retain) IBOutlet UIImageView *navbar;
#property (nonatomic,retain) IBOutlet UITableView *Table1;
#property (nonatomic,retain) IBOutlet UITableView *Table2;
#end
In .m
#implementation secondaryTable
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 2;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"MyIdentifier2";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease];
[cell.textLabel setFont:[UIFont boldSystemFontOfSize:12.0]];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.textAlignment = UITextAlignmentCenter;
}
if (indexPath.row == 0) cell.textLabel.text =#"A";
if (indexPath.row == 1) cell.textLabel.text =#"B";
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"Selected");
mainViewController *myController = [[mainViewController alloc] init];
[myController.navbar setHidden:NO];
}
#end
#implementation mainViewController
- (void)viewDidLoad {
Table1.delegate = self;
Table1.dataSource = self;
secondaryTable *myDelegate = [secondaryTable alloc];
Table2.delegate = myDelegate;
Table2.dataSource = myDelegate;
#end
}
It types "Selected" in console log, but it won't show control.
Why can't it call navbar control in mainViewController?
I would suggest doing this by having both tables point to the same delegate but, within your delegate methods, select behaviour based on which table it is. Example:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == firstTable)
{
// Do appropriate things here
}
else if (tableView == secondTable)
{
// do things for table #2 here
}
else
{
assert(no); // error checking
}
}
In the following code, I push a new UITableView when I click on a button. The TableView has 25 rows. I can see the first 9 row and the 10th row got cut off. I can't scroll down to view the rest of the rows. How do I make the TableView scrollable? Thank you.
- (IBAction)showListPicker:(id)sender {
ListPicker *lp = [[ListPicker alloc] initWithStyle:UITableViewStyleGrouped];
[self setTitle:#"Home"];
[[self navigationController] pushViewController:lp animated:YES];
[lp release];
}
The following is the declaration for ListPicker
#import <Foundation/Foundation.h>
#interface ListPicker : UITableViewController
{}
#end
The following is the implementation for ListPIcker
#import "ListPicker.h"
#import "GameStore.h"
#import "List.h"
#import "HomeViewController.h"
#implementation ListPicker
- (id)init
{
return [super initWithStyle:UITableViewStyleGrouped];
}
-(id)initWithStyle:(UITableViewStyle)style{
return [self init];
}
-(void)dealloc{
[super dealloc];
}
-(void)viewDidLoad{
[self setTitle:#"Select List"];
[[self navigationController] setNavigationBarHidden:NO];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [[[GameStore defaultStore] allLists] count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"UITableViewCell"];
if(cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"UITableViewCell"] autorelease];
}
NSArray *allList = [[GameStore defaultStore] allLists];
List *mylist = [allList objectAtIndex:[indexPath row]];
NSString *listTitle = [mylist label];
[[cell textLabel] setText:listTitle];
[cell setAccessoryType:UITableViewCellAccessoryNone];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
List *list = [[[GameStore defaultStore] allLists] objectAtIndex:[indexPath row]];
[[GameStore defaultStore] setSelectedList:list];
HomeViewController *hv = [[HomeViewController alloc] init];
[[self navigationController] popViewControllerAnimated:YES];
}
#end
Try to add:
yourTable.scrollEnabled = YES;
Also, when you create your table programmatically, make sure it is "long enough", i.e.,
CGRect cgRct = CGRectMake(0, 0, 320, 600);
yourTable = [[UITableView alloc] initWithFrame:cgRct style:UITableViewStyleGrouped];
Instead of YES, write true as it accepts only bool values.
yourTable.scrollEnabled = true;
Two common ways to change the boolean state of scrolling in a UITableView:
1) It can be enabled either in the attributes inspector of the UITableView via Storyboard.
2) Or programmatically inside your viewDidLoad() via ViewController.
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var yourTable: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// assign delegate and datasource
yourTable.delegate = self
yourTable.dataSource = self
//enable UITableView scrolling in Swift 3 and Swift 4.
yourTable.isScrollEnabled = true
}
}
i am displaying a list of items in a tableview.i need to select and delete multiple rows from the table at a time,any resources on how to do this
I'm assuming your table has just one section. You can extend this solution to multiple sections fairly easily.
Add an NSMutableSet member "selectedRows" to your UIViewController subclass that manages your TableView
in - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath toggle the indexPath.row's membership in "selectedRows", like this:
NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:indexPath.row];
if ( [self.selectedRows containsObject:rowNsNum] )
[self.selectedRows removeObject:rowNsNum];
else
[self.selectedRows addObject:rowNsNum];
indicate visually that a row is selected (e.g., set the cell's accessoryType property to UITableViewCellAccessoryCheckmark), or modify your cell visually in some other way to indicate that it is a selected row
add a "delete" button to your UI, either in a table section header/footer, your title bar, anywhere, hooked up to a selector called "deleteRows"
in your deleteRows method, iterate through the selectedRows set, building up an array of indexPaths, delete these rows from your data model, then call (with your preferred animation type):
[self.myTableView deleteRowsAtIndexPaths:arrayOfIndexPathsToDelete withRowAnimation:UITableViewRowAnimationTop];
EDIT:
Here's my full didSelectRowAtIndexPath method. The deselectRowAtIndexPath may be required for correct operation.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ( self.editing )
return;
[self.myTableView deselectRowAtIndexPath:indexPath animated:YES];
NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:indexPath.row];
if ( [self.selectedRows containsObject:rowNsNum] )
[self.selectedRows removeObject:rowNsNum];
else
[self.selectedRows addObject:rowNsNum];
[self.myTableView performSelector:#selector(reloadData) withObject:nil afterDelay:0.2];
}
#import "ViewController.h"
#import "TableViewCell.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UITableView *tblView;
#property (strong,nonatomic)NSMutableArray *arryData1,*arryData2;
#property (strong,nonatomic)UIBarButtonItem *edit,*delete;
#end
#implementation ViewController
{
BOOL Selected;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.arryData1 = [[NSMutableArray alloc] initWithObjects:#"MCA",#"MBA",#"BTech",#"MTech",nil];
self.arryData2 = [[NSMutableArray alloc] initWithObjects:#"Objective C",#"C++",#"C#",#".net",nil];
self.edit=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:#selector(edit:)];
self.navigationItem.leftBarButtonItem=self.edit;
self.delete=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:#selector(delete:)];
self.navigationItem.rightBarButtonItem=self.delete;
self.tblView.allowsMultipleSelection=YES;
}
-(void)edit:(id)sender
{
Selected=YES;
[self.tblView reloadData];
}
-(void)delete:(id)sender
{
NSArray *selectedCells = [self.tblView indexPathsForSelectedRows];
NSMutableIndexSet *indicesToDelete = [[NSMutableIndexSet alloc] init];
for (NSIndexPath *indexPath in selectedCells) {
[indicesToDelete addIndex:indexPath.row];
}
//arrayFromPlist is NSMutableArray
[self.arryData1 removeObjectsAtIndexes:indicesToDelete];
[self.tblView beginUpdates];
[self.tblView deleteRowsAtIndexPaths:selectedCells withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tblView endUpdates];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
// Remove the row from data model
[self.arryData1 removeObjectAtIndex:indexPath.row];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.arryData1 count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier= #"Cell";
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] ;
}
if (Selected==YES) {
cell.imageView.image=[UIImage imageNamed:#"trash.png"];
}
else
{
cell.imageView.image=nil;
}
cell.textLabel.text = [self.arryData1 objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [self.arryData2 objectAtIndex:indexPath.row];
return cell;
}
#end