I have two button when i click on btn1 UITableview display same as below image 1 and i click on btn2 UIableView display same as below image 2
I am using custom cell. I have done with table reload but it display "checkbox" in both UITableview.
BOOL isChecked;
isChecked = true;
-(IBAction)btn1:(id)sender
{
isChecked = true;
[self.mytableview reload];
}
-(IBAction)btn2:(id)sender
{
isChecked = false;
[self.mytableview reload];
}
cellRowAtIndexPath method in:
if(isChecked)
{
customcell.trLabel.text = [arr1 objectAtIndex : indexpath.row]
[customcell.button setImage:[UIImage imageNamed:#"checked.png"] forState:UIstateselected];
[customcell.button setImage:[UIImage imageNamed:#"unchecked.png"] forState:UIstateNormal];
[customcell.button addTarget:self action:#selector(checkButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
}
else
{
customcell.trLabel.text = [arr2 objectAtIndex : indexpath.row]
[customcell.buttton = NULL;
}
difrent method
-(void)checkButtonTapped:(id)sender
{
sender.selected = !sender.selected;
}
image 1
image 2
i have done select all.
didSelect Method:
DemoTableViewCell *cell;
if(indexPath.row == 0)
{
for (int i = 0; i < [self.tableview1 numberOfSections]; i++) {
for (int j = 0; j < [self.tableview1 numberOfRowsInSection:i]; j++) {
NSUInteger ints[2] = {i,j};
NSIndexPath *indexPath = [NSIndexPath indexPathWithIndexes:ints length:2];
cell = (DemoTableViewCell *)[self.tableview1 cellForRowAtIndexPath:indexPath];
//Here is your code
UIButton *btn = cell.button;
if( [[btn imageForState:UIControlStateNormal] isEqual:[UIImage imageNamed:#"checked.png"]])
{
[btn setImage:[UIImage imageNamed:#"unchecked.png"] forState:UIControlStateNormal];
// other statements
}
else
{
[btn setImage:[UIImage imageNamed:#"checked.png"] forState:UIControlStateNormal];
}
}
}
}
else
{
cell = (DemoTableViewCell *)[self.tableview1 cellForRowAtIndexPath:indexPath];
UIButton *btn = cell.button;
if( [[btn imageForState:UIControlStateNormal] isEqual:[UIImage imageNamed:#"checked.png"]])
{
[btn setImage:[UIImage imageNamed:#"unchecked.png"] forState:UIControlStateNormal];
// other statements
}
else
{
[btn setImage:[UIImage imageNamed:#"checked.png"] forState:UIControlStateNormal];
}
}
My question is:
1) select all option select all "checkbox" that is done but when i "uncheck" any item of them select all option also be "uncheck".
2) Not display "checbox" in image 2 UITablevieCell.
3) When i "uncheck" item3 and click again select all option deselect all "checkbox" except item3 and item3 is checked.
Solution to 2) Not display "checbox" in image 2 UITablevieCell
You need to create a different prototype cell with no checkbox.
Then in cellRowAtIndexPath method use that cell if button 2 was clicked
For other questions, you need to store the state of each checkbox (in array or dictionary) . Then in cellRowAtIndexPath method depending on the state of checkbox in that row, tick or untick the checkbox of the cell
1) Have NSMutableArray in your ViewController where you would store all your checkboxes state (ticked or unticked).
2) In the method that is called when checkbox is ticked/unticked, update 1 or 0 in the array like:
- (void) actionCheckbox {
self.mydata[indexPath.row] = 1; // set 0 or 1
[self.tableview reloadRowsAtIndexPath ...]; // Don't remember exact method name
}
3) In cellRowAtIndexPath,
if(self.mydata[indexPath.row] == 1) {
// tick checkbox for this row
} else {
// untick checkbox for this row
}
Related
I have a UIButton click sender as below:-
-(IBAction)clipButtonClick:(UIButton *)sender
{
sender.selected = ! sender.selected;
if (sender.selected)
{
[btnClipCategory setImage:[UIImage imageNamed:#"imgClip_HL"] forState:UIControlStateSelected];
NSMutableArray* indexArray = [NSMutableArray array];
for (NSInteger i = 0; i < self.arySubCategory.count; i++)
{
[aryCheckCategoryList replaceObjectAtIndex:i withObject:#"YES"];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
[indexArray addObject:indexPath];
dispatch_async(dispatch_get_main_queue(), ^{
[self.rightTableView reloadData];
});
}
}
else
{
[btnClipCategory setImage:[UIImage imageNamed:#"imgClip"] forState:UIControlStateNormal];
NSMutableArray* indexArray = [NSMutableArray array];
for (NSInteger i = 0; i < self.arySubCategory.count; i++)
{
[aryCheckCategoryList replaceObjectAtIndex:i withObject:#"NO"];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
[indexArray addObject:indexPath];
dispatch_async(dispatch_get_main_queue(), ^{
[self.rightTableView reloadData];
});
}
}
}
When I clicked on the button, sender will always hit on selected option.
If i change the sender to code to sample code as below, my apps will working properly as expected. Any idea? Please help. Thank you.
-(IBAction)clipButtonClick:(UIButton *)sender
{
sender.selected = ! sender.selected;
if (sender.selected)
{
[btnClipCategory setImage:[UIImage imageNamed:#"imgClip_HL"] forState:UIControlStateSelected];
NSLog(#"Selected. Will Hit here");
}
else
{
[btnClipCategory setImage:[UIImage imageNamed:#"imgClip"] forState:UIControlStateNormal];
NSLog(#"Non Selected. Will Hit here");
}
}
Edited
I put my button under willDisplayHeaderView.
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section{
UITableViewHeaderFooterView *header = (UITableViewHeaderFooterView *)view;
btnClipCategory = [UIButton buttonWithType:UIButtonTypeCustom];
[btnClipCategory setFrame:CGRectMake(header.frame.size.width - 45, header.frame.size.height * 0.2, ScreenW * 0.1, ScreenW * 0.1)];
[btnClipCategory addTarget:self action:#selector(clipButtonClick:) forControlEvents:UIControlEventTouchUpInside];
[header addSubview:btnClipCategory];
}
When you call [self.rightTableView reloadData], all the content of the table view including sections headers gets reloaded, and tableView:willDisplayHeaderView:forSection: gets called for each visible section header. So your bntClipCategory gets recreated with default value of isSelected each time click action fires.
You don't reload rightTableView in your working code sample, that's why it works.
You should reconsider you approach. One of the options is to save isSelected state of buttons for each section in array and update btnClipCategory.isSelected accordingly before adding it to header view.
I am working on a functionality regarding a button click, where my requirement is I have only one button, if a button is clicked 1st time add a label, if same button is clicked for 2nd time add another label, like 5 time button is clicked 5 labels should be added.
-(IBAction) btnAddClicked: (id) sender {
if (_btnAdd.tag == 0) {
_lblAdd1.hidden = YES;
}
if (_btnAdd.tag == 1) {
_lblAdd2.hidden = YES;
}
if (_btnAdd.tag == 2) {
_lblAdd3.hidden = YES;
}
if (_btnAdd.tag == 3) {
_lblAdd4.hidden = YES;
}
}
You have to determine which button is sending the event
-(IBAction)btnAddClicked: (id) sender {
//Typecast to retrieve tag of current button.
UIButton *btn = (UIButton * ) sender;
if (btn.tag == 0) {
_lblAdd1.hidden = YES;
}
if (btn.tag == 1) {
_lblAdd2.hidden = YES;
}
if (btn.tag == 2) {
_lblAdd3.hidden = YES;
}
if (btn.tag == 3) {
_lblAdd4.hidden = YES;
}
}
You can update tag based on clicks.if you want more than one you can continue or else last click you set button tag as 0.
-(IBAction)btnAddClicked: (id) sender {
UIButton *btn = (UIButton * ) sender;
if (btn.tag == 0) {
_lblAdd1.hidden = YES;
btn.tag = 1;
}
else if (btn.tag == 1) {
_lblAdd2.hidden = YES;
btn.tag = 2;
}
else if (btn.tag == 2) {
_lblAdd3.hidden = YES;
btn.tag = 3;
}
else if (btn.tag == 3) {
_lblAdd4.hidden = YES;
btn.tag = 0;
}
to ways to do this
1 Use TableView who's cell contains a textFld , each time when you click the button, Update the UITableView By Number of cells one more the last count ..
Example : On first Click add indexPath/number/etc to a mutable array and reload the the tableview for count of that array, table cell will create for one cell ..
Now On second click add one more to that array and reload the tableview, now tableview will create cells for the array count which is now 2 ... SO On. hope you are getting it
The below code is for n number of dynamic textfields creation:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _count; }
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TextViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
return cell; }
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{
UIView *footerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 30)];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 30)];
[button setTitle:#"Add TextField" forState:UIControlStateNormal];
button.backgroundColor = [UIColor blueColor];
[button addTarget:self action:#selector(addTextField) forControlEvents:UIControlEventTouchUpInside];
[footerView addSubview:button];
return footerView; }
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
return 30; }
-(void)addTextField{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:_count inSection:0];
_count++;
[self.tableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; }
Before asking this question I googled a lot but not able to find suitable answer.
I'm have a UITableView with n number of Columns. The thing is the Column is Grouped according to a key. So my UITableView header is splitted into two, one for the column group and and this column group is divided to show columns.
I have created a custom class for the cell there I display radio button in each column.
Code:
In cellForRowAtIndexPath method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
GridTableViewCell *cell = nil; // My custom class for cell
CGFloat startX = 230;
if (cell == nil)
{
cell = [[GridTableViewCell alloc] initWithStyle1:UITableViewCellStyleDefault reuseIdentifier:#"Cell" withRows:[self.rowHeaderArray objectAtIndex:indexPath.row]];
for (int i = 0; i < [self.groupColumNmeArray count]; i++) { // groupColumNmeArray contains the Column Group name
NSArray *values = [_subColumnDict objectForKey:[self.groupColumNmeArray objectAtIndex:i]]; // subColumnDict contains the value for each column
self.originalDataArray = [CustomTableHeaderParser parseColumnInfo:values];// Parsing the values array for getting column name, type, width etc
for (CustomTableColumn *column in self.originalDataArray)
{
switch (column.columnType) // acc. to column type display the cell with values.
{
case RadioBtn:
{
_btTemp = [[UIButton alloc]initWithFrame:CGRectMake(startX, 2, subCellWidth , 40)];
[_btTemp setTag:indexPath.row];//indexPath.row];
[_btTemp addTarget:self action:#selector(radioButtonsClicked:) forControlEvents:UIControlEventTouchUpInside];
[_btTemp setImage:[UIImage imageNamed:#"radio-off.png"] forState:UIControlStateNormal];
[_btTemp setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
_btTemp.titleLabel.font =[UIFont systemFontOfSize:14.f];
[self.radioButtons addObject:_btTemp];
[cell addSubview:_btTemp];
}
break;
startX += 2+subCellWidth;
}
}
}
cell.selectedBackgroundView = [[UIView alloc] initWithFrame:cell.frame];
cell.selectedBackgroundView.opaque = YES;
return cell;
}
Radio button click action method;
-(IBAction) radioButtonsClicked:(UIButton *) sender {
if ([sender isSelected]) {
[sender setSelected: NO];
[sender setImage:[UIImage imageNamed:#"radio-off.png"] forState:UIControlStateNormal];
} else {
[sender setSelected: YES];
[sender setImage:[UIImage imageNamed:#"radio-on.png"] forState:UIControlStateNormal];
}
NSLog(#"BUTTON TAG %ld",(long)sender.tag);
}
So I'm able to make selections for radio buttons in all column but actually what I want is For each column group only one radio button is selectable.
Can anybody help me. Any help would be greatly appreciable.
You can set other button's selection status as following
-(IBAction) radioButtonsClicked:(UIButton *) sender {
sender.selected = !sender.selected;
for (UIView *vw in sender.superview.subviews)
{
if([vw isKindOfClass:[UIButton class]] && vw != sender)
{
UIButton *otherBtn = (UIButton*)vw;
otherBtn.selected = NO;
}
}
}
for setting button Image - on/off, write that code at the time of creating button in cellforrow..
[_btTemp setImage:[UIImage imageNamed:#"radio-off.png"] forState:UIControlStateNormal];
[_btTemp setImage:[UIImage imageNamed:#"radio-on.png"] forState:UIControlStateSelected];
I have students attendance list in UITableView. Where each cell having an UIButton to set student attendance like Present, Absent and Leave on button click. How can I achieve this on single button.
You can do this by simply implementing the following #selector for your UIButton in UITableViewCell.
- (void)btnSetMode:(id)sender
{
UIButton *btn = (UIButton *)sender;
if (btn.tag == 0)
{
[btn setTitle:#"Present" forState:UIControlStateNormal];
btn.tag = 1;
// Define your required task...
}
else if (btn.tag == 1)
{
[btn setTitle:#"Absent" forState:UIControlStateNormal];
btn.tag = 2;
// Define your required task...
}
else if (btn.tag == 2)
{
[btn setTitle:#"Leave" forState:UIControlStateNormal];
btn.tag = 3;
// Define your required task...
}
else if (btn.tag == 3)
{
[btn setTitle:#"Attendance" forState:UIControlStateNormal];
btn.tag = 0;
// Define your required task...
}
}
Your single button will do all the required task as you wanted.
If you have An UIButton in your tableViewCell then add Target to your UIButton and set button Tag with indexPath.row in cellForRowAtIndexPath like-
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
attendanceListTableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:#"cell"];
cell.studentNameLbl.text=[NSString stringWithFormat:#"Student %ld",(long)indexPath.row];
cell.editBtn.tag=indexPath.row;
[cell.editBtn setTitle:[attandanceArry objectAtIndex:indexPath.row] forState:UIControlStateNormal];
[cell.editBtn addTarget:self action:#selector(editAttendance:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
-(void)editAttendance:(id)sender{
UIButton *btn=(UIButton*)sender;
if ([btn.titleLabel.text isEqualToString:#"P"]) {
[btn setTitle:#"A" forState:UIControlStateNormal];
[attandanceArry replaceObjectAtIndex:btn.tag withObject:#"A"];
}else if ([btn.titleLabel.text isEqualToString:#"A"]) {
[btn setTitle:#"L" forState:UIControlStateNormal];
[attandanceArry replaceObjectAtIndex:btn.tag withObject:#"L"];
}else if ([btn.titleLabel.text isEqualToString:#"L"]) {
[btn setTitle:#"P" forState:UIControlStateNormal];
[attandanceArry replaceObjectAtIndex:btn.tag withObject:#"P"];
}
}
In this attandanceArry is mutableArray having all default value is "P" with capacity of your number of students and editBtn is your cell UIButton. Here I use custom tableViewCell class i.e. attendanceListTableViewCell class having UIButton. At the end you can use attandanceArry as result array when you complete editing attendance. I hope this will help you...:)
Change the button title and background color when it's clicked. Personally, I would use three different buttons so that all different options would be visible at the same time. UIPicker is one option too.
Is a UISegmentedControl what you are looking for?
See the Apple Documentation here. It can be configured in a storyboard with the correct number of segments and segment titles. When the user selects a segment it will be highlighted, and any other segments are deselected.
I have a collection view where each cell contains 7 buttons, (created via code not storyboard).
They are sharp initially, however if I scroll up / down a few times the quality decreases.
The sharpness is restored when I change views and return.
Any ideas ?
Addit:
I am making the buttons like this, within a loop (can be 1 to 7 buttons)
- (UICollectionViewCell*) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"patientCell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
Patient *aPt = [self.fetchedResultsController objectAtIndexPath:indexPath];
PatientCVCell *ptCell = (PatientCVCell *) cell;
ptCell.ptName.text = aPt.name;
ptCell.ptRoom.text = aPt.room;
ptCell.ptRx.text = aPt.diagnosis;
int xPos = 20;
NSArray *daysForRx = aPt.ofList.listDays;
// loop through to add button for each day of Rx
for (int i = 0; i < [daysForRx count]; i++) {
// get the treatment day that == postition in array
for (Treatment *t in aPt.patientRx) {
if (t.day == daysForRx[i]) {
//NSLog(#"%i", xPos);
StatusButton *testButton = [StatusButton buttonWithType:UIButtonTypeCustom];
testButton.frame = CGRectMake(xPos, 110, 28, 28);
testButton.btnTreatment = t;
// match status of the RX to the correct button
if ([t.status intValue] == NotSeen) {
[testButton setImage:[UIImage imageNamed:#"toSee"] forState:UIControlStateNormal];
testButton.linkNumber = NotSeen;
}
else if ([t.status intValue] == SeenNotCharted) {
[testButton setImage:[UIImage imageNamed:#"seenNotCharted"] forState:UIControlStateNormal];
testButton.linkNumber = SeenNotCharted;
}
else if ([t.status intValue] == SeenCharted) {
[testButton setImage:[UIImage imageNamed:#"seenCharted"] forState:UIControlStateNormal];
testButton.linkNumber = SeenCharted;
}
else if ([t.status intValue] == NotSeeing) {
[testButton setImage:[UIImage imageNamed:#"notSeeing"] forState:UIControlStateNormal];
testButton.linkNumber = NotSeeing;
}
else if ([t.status intValue] == NotSeeingDC) {
[testButton setImage:[UIImage imageNamed:#"notSeeingDischarged"] forState:UIControlStateNormal];
testButton.linkNumber = NotSeeingDC;
}
[testButton addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:testButton];
xPos = xPos + 36;
}
}
}
return cell;
}
The image is correct size so no need to scale the image.
Occurs in simulator and on device.
After looking more closely, the inside of the images are sharp! So this issue has to do with the transparency for my circle shape of a button within a square button!
You are dequeuing a cell, then you add your buttons to the dequeued cell.
Those buttons never get removed. When you scroll up and down cells that go off screen are put on the dequeue queue. At this time they still have the buttons, then they are dequeued and you add more buttons. You have many buttons above each other, and that's why it looks blurry and your memory footprint gets bigger.
I would add the buttons from inside the cell. Save them in a array so you can remove them later. Then I would add a method to set the number of buttons you'll need. Like this:
// header
#property (strong, nonatomic) NSMutableArray *buttons;
// implementation
- (void)setNumberOfButtons:(NSInteger)numberOfButtons withTarget:(id)target selector:(SEL)selector {
// remove existing buttons from view
[self.buttons makeObjectsPerformSelector:#selector(removeFromSuperview)];
// "save" existing buttons in a reuse queue so you don't have to alloc init them again
NSMutableArray *reuseQueue = self.buttons;
self.buttons = [NSMutableArray arrayWithCapacity:numberOfButtons];
for (NSInteger i = 0; i < numberOfButtons; i++) {
UIButton *button = [reuseQueue lastObject];
if (button) {
[reuseQueue removeLastObject];
}
else {
button = [UIButton buttonWithType:UIButtonTypeCustom];
// you should always use the same target and selector for all your cells. otherwise this won't work.
[button addTarget:target action:selector forControlEvents:UIControlEventTouchUpInside];
}
[self.buttons addObject:button];
button.frame = ....
// don't set up images or titles. you'll do this from the collectionView dataSource method
}
}
you would then set the number of buttons in collectionView:cellForItemAtIndexPath: and configure each button according to your needs. something along those lines:
- (UICollectionViewCell*) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
Cell *cell = ... dequeue ...
Object *object = ... get from your backend ...
/* configure your cell */
if ([cell.buttons count] != object.numberOfItems) {
// no need to remove and add buttons if the item count stays the same
[cell setNumberOfButtons:object.numberOfItems withTarget:self selector:#selector(buttonPressed:)];
}
for (NSInteger i = 0; i < [object.numberOfItems count]; i++) {
UIButton *button = cell.buttons[i];
[button setImage:... forState:UIControlStateNormal];
}
}
And the action would look like this:
- (IBAction)buttonPressed:(UIButton *)sender {
UICollectionView *collectionView;
CGPoint buttonOriginInCollectionView = [sender convertPoint:CGPointZero toView:collectionView];
NSIndexPath *indexPath = [collectionView indexPathForItemAtPoint:buttonOriginInCollectionView];
NSAssert(indexPath, #"can't calculate indexPath");
Cell *cell = [collectionView cellForItemAtIndexPath:indexPath];
if (cell) {
NSInteger pressedButtonIndex = [cell.buttons indexOfObject:sender];
if (pressedButtonIndex != NSNotFound) {
// do something
}
}
else {
// cell is offscreen?! why?
}
}
pretty straight forward. Get the indexPath, get the collectionViewCell, check which index the pressed button has