I want to change the accessory view of the cell. When the user clicks on the right navigation bar item an action occurs, in that action i want to change the accessory view. how can i do this, when i used this code its asking for NSindexPath thing so i have no which value i can give here , in order to change the view of all cells.
MyCustomCell *cell = (MyCustomCell *) [self.tableView cellForRowAtIndexPath:helloIndexPath];
if( cell.accessoryType == UITableViewCellAccessoryDisclosureIndicator)
{
cell.accessoryView = [[UIImageView alloc]initwithImage:[UIImage imageNamed:#"hello.png"]];
}
I guess you should put condition in table view - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
Here you can put a if-condition.
if(flagForAction){
cell.accessoryView = [[UIImageView alloc]initwithImage:[UIImage imageNamed:#"hello.png"]];
}
else
{
cell.accessoryView = [[UIImageView alloc]initwithImage:[UIImage imageNamed:#"<no-Hello>.png"]];
}
All you need to do is set your flag and reload table at action. by calling [<your table> reloadData];
Related
I have a custom UITableViewCell, and when it's selected, it expands and adds a UILabel to the selected cells UIView that I added in the storyBoard.
When I run the app and select a cell, the label gets added to myView as expected. The problem is, when I scroll down, the label is also shown at another cell.
Apparently the reason its behaving like so, is because I'm reusing the cell and I don't clean them as Emilie stated. I'm trying to call the method of prepareForReuse and 'cleaning' the cell, but I'm having trouble doing that. Here is my code:
- (void)prepareForReuse {
NSArray *viewsToRemove = [self.view subviews];
for (UILablel *v in viewsToRemove) {
[v removeFromSuperview];
}
Doing that, cleans even the selected cells label.
- (void)viewDidLoad {
self.sortedDictionary = [[NSArray alloc] initWithObjects:#"Californa", #"Alabama", #"Chicago", #"Texas", #"Colorado", #"New York", #"Philly", #"Utah", #"Nevadah", #"Oregon", #"Pensilvainia", #"South Dekoda", #"North Dekoda", #"Iowa", #"Misouri", #"New Mexico", #"Arizona", #"etc", nil];
self.rowSelection = -1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CategorieCell *customCell = [tableView dequeueReusableCellWithIdentifier:#"cellID" forIndexPath:indexPath];
customCell.title.text = [self.sortedDictionary objectAtIndex:indexPath.row];
return customCell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
CategorieCell *customCell = (CategorieCell *)[tableView cellForRowAtIndexPath:indexPath];
if (self.info) {
[self.info removeFromSuperview];
}
self.info = [[UILabel alloc] init];
[self.info setText:#"Hello"];
[self.info setBackgroundColor:[UIColor brownColor]];
CGRect labelFrame = CGRectMake(0, 0, 50, 100);
[self.info setFrame:labelFrame];
[customCell.infoView addSubview:self.info];
NSLog(#"%ld", (long)indexPath.row);
self.rowSelection = [indexPath row];
[tableView beginUpdates];
[tableView endUpdates];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([indexPath row] == self.rowSelection) {
return 159;
}
return 59;
}
The answer is quite simple : you reuse your cell like you should, but never clean them
Reusing your UITableViewCell means that the cell you clicked on previously will be reused when it will go off-screen.
When clicked, you add a view to your UITableViewCell. When reused, the view is still there because you never remove it.
You have two choices : One, you could set a tag of the self.info view (or check with the indexpath you're keeping in memory), then check when you dequeue the cell if the info view is there, and remove it. The cleaner solution would be to implement the view removal by overriding the prepareForReuse method of your custom UITableViewCell
Precision
The first thing you need to do is set a tag for your self.info view after initializing it:
[self.info setTag:2222];
If you want to keep it as simple as possible, you could check and remove the self.info view directly in your cellForRowAtIndexPath method :
CategorieCell *customCell = [tableView dequeueReusableCellWithIdentifier:#"cellID" forIndexPath:indexPath];
customCell.title.text = [self.sortedDictionary objectAtIndex:indexPath.row];
if [customCell.infoView viewWithTag: 2222] != nil {
[self.info removeFromSuperview]
}
return customCell;
I am not a percent sure this code compiles, I cannot test it on my side for now. Hope it works !
Creating the UIpickerview in tableview button click. When click the each button first time the picker want to show . if i click the same button in another time picker want to hide and get the picker value. here i put my code only the last cell index done the process the first cell index is not working? how can i fix this issues help me!!! here screen!.
create the picker in global like
UIPickerView *myPickerView;` and acess in tableview
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [_arr_tags count]; /// in tag array number of button count
}
-(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:nil];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
/// create a button
UIImage *ButtonImagecmt = [UIImage imageNamed:#"orangeButton#2x.png"];
UIButton *myButtoncmt = [UIButton buttonWithType:UIButtonTypeRoundedRect];
myButtoncmt.frame = CGRectMake(10,50,90,35);
[myButtoncmt setBackgroundImage:ButtonImagecmt forState:UIControlStateNormal];
[myButtoncmt addTarget:self action:#selector(picker_select:)forControlEvents:UIControlEventTouchDown];
[cell addSubview:myButtoncmt];
flg=1; /// first time picker want to hide so flag set 1.
myPickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(120, 0, 160, 180)];
myPickerView.delegate = self;
myPickerView.showsSelectionIndicator = YES;
myPickerView.hidden=true;
[cell addSubview:myPickerView];
}
return cell;
}
- (IBAction)picker_select:(id)search
{
if (flg==1)
{
/// first time button clickt picker want to display
myPickerView.hidden=false;
flg=0;
}
else
{
/// secound time button click picker want to hide
myPickerView.hidden=true;
flg=1;
}
}
This code only working in last cell. want to work in all the cell in table view
First let me explain your error after that I will suggest you other way.
You are declaring UIPickerView *myPickerView; in out side of following method
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
But you are initializing myPickerView inside of following method
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
and again you are trying to access myPickerView outside of the following method
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
simply the object myPickerView represents last cell pickerview. so what ever button you tapped in table view, myPickerView always represents last cell pickerview. As per reusability concept, you can't see this picker until you are loading last cell on screen.
so what I am suggesting you to work with your code
set index row as tag to your button like bellow in cellForRowAtIndexPath method
myButtoncmt.tag = indexpath.row;
now in the same way set tag to your pickerview also(I am not recommended this but I am trying to resolve issue with your code ) like bellow
myPickerView.tag = [_arr_tags count]+indexpath.row;
Now in - (IBAction)picker_select:(id)search access that using following code
UIButton *tempBtn =(UIButton *) search;
UITableViewCell *cell= [_tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:tempBtn.tag inSection:0]]
UIPickerView *pickerView = [cell viewWithTag:[_arr_tags count]+tempBtn.tag];
pickerView.hidden = !pickerView.isHidden;
Now you can see all pickers. try and let me know your result
I'm having a custom cell that I create like this:
CategoryCellTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:#"poiCell"];
if (!cell)
{
cell = [[CategoryCellTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"poiCell"];
}
// Get current POI
Rank * poi = [_data objectAtIndex:indexPath.row];
cell.text.text = poi.name;
cell.categoryImageView.image = [UIImage imageNamed:#"animals.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"map"]];
cell.accessoryView = imageView;
return cell;
The accessoryView shows up. But when I click on it, it doesn't come in my:
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Accessory clicked");
}
Do I need to set some delegate right? I thought this was already implemented for you so you could always use it?
You need your own handler for you custom view. This delegate method called only for default accessory button.
For example you may add custom UIButton with image as accessory view and add target and action to this button.
I have problem with my custom tableview cell button click event with load activity indicator on selected cells button.
If you have link or other source then please help me out.
I am new in iOS development.
This is significantly easier because it doesn't involve any third party stuff (even though MBProgressHUD is a great tool). When I created the cell, I created a UIACtivityIndicatorView and added it as the cell's accessoryView. Later, when a row is pressed, I grab a reference to the cell itself at the appropriate indexPath, and then access its accessoryView property, which is the indicator view. From there you can just tell it to start animating.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
cell.accessoryView = activityIndicator;
}
cell.textLabel.text = _items[indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// deselect the row if you want the cell to fade out automatically after tapping
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// get a reference to the cell that the user tapped
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
// get the tapped cell's accessory view and cast it as the activity indicator view
UIActivityIndicatorView *activityIndicator = (UIActivityIndicatorView *)cell.accessoryView;
// tell it to start animating
[activityIndicator startAnimating];
}
This results in the following after tapping the first cell:
You'll have to change the code a bit depending on when/how you want to stop the activity indicator from spinning, but without have more information from you this is the best info I can provide. You'll likely want to add the indexPath.row integer to the progressView's tag property, but there's a bit more to that. Hope this helps!
EDIT
Add a tag to the button that's the indexPath of the row, and do something like:
- (void)showProgressViewForButton:(id)sender {
NSInteger tappedCellIndex = sender.tag;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:tappedCellIndex inSection:0];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
UIActivityIndicatorView *activityIndicator = (UIActivityIndicatorView *)cell.accessoryView;
[activityIndicator startAnimating];
}
here is the link for MBProgressHUD:
https://github.com/jdg/MBProgressHUD
I want to create a view like this in my iPhone App:
I do not know exactly what is this control in iOS, that maybe I can set an icon and text in the left side and that small sign in the right side.
I have implemented a TableView, there I was able to set these stuff, like this:
[[cell textLabel] setText:customer.name];
[[cell textLabel] setTextColor:[UIColor blackColor]];
[[cell imageView] setImage:[UIImage imageNamed:#"icon.png"]];
//[[cell detailTextLabel] setText:#"Awsome weather idag"];
cell.accessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
But how can I make it works like that view in the picture?
It is pretty simple, follow the steps below and in case of doubts check out the UITableView documentation:
1. Create a grouped table view:
Programmatically:
CGRect tableFrame = CGRectMake(0, 0, 200, 200);
UITableView *tableView = [[UITableView alloc] initWithFrame:tableFrame style:UITableViewGroupedStyle];
tableView.delegate = self;
tableView.dataSource = self;
[self.view addSubview:tableView];
Allocating a UITableViewController subclass (common case):
MyTableViewController *controller [[MyTableViewController alloc] initWithStyle: UITableViewGroupedStyle];
[self.navigationController pushViewController:controller animated:NO];
Through Interface Build:
Expand the Utilities Menu (top right corner icon);
Select your table view (click on it);
Click on the attributes inspector (top right corner fourth icon);
Under Table View, click on the style dropdown and select grouped.
2. Implement the UITableViewDataSource protocol:
Basically add this three functions to your controller.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in a given section.
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Configure the cells.
return cell;
}
3. Configuring the cells:
The default style of a UITableViewCell has an image view (UIImageView), a title label (UILabel) and an accessory view (UIView). All you need to replicate the table view in the image you provided.
So, you're looking for something like this in tableView:cellForRowAtIndexPath::
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString * const cellIdentifierDefault = #"default";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifierAccount];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifierAccount];
}
if (indexPath.section == 0) {
cell.imageView.image = [UIImage imageName:#"bluetooth_icon"];
cell.textLabel.text = #"Bluetooth";
// Additional setup explained later.
}else{
if (indexPath.row == 0) {
cell.imageView.image = [UIImage imageName:#"general_icon"];
cell.textLabel.text = #"General";
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}else{
cell.imageView.image = [UIImage imageName:#"privacy_icon"];
cell.textLabel.text = #"Privacy";
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
}
return cell;
}
The property accessoryType defines what is going to appear on the right side of a cell, a list of accessory types can be found here.
In the first cell (bluetooth), you'll need to create a custom accessory view and assign it to the cell's accessoryView property. A very naive example of how to achieve this is given below:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString * const cellIdentifierDefault = #"default";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifierAccount];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifierAccount];
label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 44)];
label.textAlignment = NSTextAlignmentRight;
cell.accessoryView = label;
}else{
label = (UILabel *) cell.accessoryView;
}
cell.imageView.image = [UIImage imageName:#"bluetooth_icon"];
cell.textLabel.text = #"Bluetooth";
label.text = #"Off";
return cell;
}
Hope this helps, Mateus
For fast output, you can use some library like
https://github.com/escoz/QuickDialog
protip, in my experience, solutions like this leaves you more tangled when Changes come in.
Some times you only want to change one specific label on once specific view, thats not gona be easy in any ready-made solution.
Look into UITableView Sections. That is what separates the groups apart.