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]; }
Related
How to get a UISwitch tag from multiple sections. I have 3 sections, user can change switch status. Based on that I want to get that switch tag and section index.
You can set previously
switch.accessibilityValue = "\(indexPath.section)"
and get back
let section = Int(cell.accessibilityValue ?? "0")
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 50)];
UISwitch *onoff = [[UISwitch alloc] initWithFrame: CGRectMake(0, 0, 100, 50)];
[onoff addTarget: self action: #selector(flip:)
forControlEvents:UIControlEventValueChanged];
onoff.tag = section;
[view addSubview: onoff];
}
- (IBAction)flip:(id)sender
{
if(sender.tag == 0)
{
//Do whatever you want to do.
}
else if(sender.tag == 1){
//You can add as many as you want.
}
}
One more thing you need to know about header in the table view that to override header height. You can do it like this :
- (CGFloat)tableView:(UITableView *)tableView
heightForHeaderInSection:(NSInteger)section
{
return 50;
}
This is the answer, it's worked for me....
UITableViewCell *cell = (UITableViewCell *)mySwitch.superview.superview;
NSIndexPath *indexpath = [_deviceRulesTableView indexPathForCell:cell];
NSLog(#"toggle section %ld rowID %ld", (long)indexpath.section, (long)indexpath.row);
if (indexpath.section == 1) {
}
I have this collapsable UITableView where there is a UITextField and a UIButton in the last cell in each table section. I would like to send the text in the UITextField to the function that is called by the UIButton that is next to it in the same cell, but I am baffled in how to achieve this. Thanks in advance for the help!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:nil];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if ([self tableView:_tableView canCollapseSection:indexPath.section])
{
int num = 1;
if (self.chat[indexPath.section - 1][#"num"] != nil)
num = [self.chat[indexPath.section - 1][#"num"] intValue] + 1;
if (!indexPath.row)
{
cell.textLabel.text = self.chat[indexPath.section - 1][#"msg"]; // only top row showing
if ([expandedSections containsIndex:indexPath.section])
{
cell.accessoryView = [DTCustomColoredAccessory accessoryWithColor:[UIColor grayColor] type:DTCustomColoredAccessoryTypeUp];
}
else
{
cell.accessoryView = [DTCustomColoredAccessory accessoryWithColor:[UIColor grayColor] type:DTCustomColoredAccessoryTypeDown];
}
}
else if (indexPath.row < num && indexPath.row >= 1)
{
cell.textLabel.text = self.chat[indexPath.section - 1][key];
cell.accessoryView = nil;
}
else
{
///////////////////////////////////////////
////////This is the important part/////////
///////////////////////////////////////////
UITextField *field = [[UITextField alloc] initWithFrame:CGRectMake(14, 6, 245, 31)];
self.sendButton = [[UIButton alloc] initWithFrame:CGRectMake(265, 1, 50, 40)];
[self.sendButton setTitle:#"Reply" forState:UIControlStateNormal];
[self.sendButton setTitleColor:UIColorFromRGB(0x960f00) forState:UIControlStateNormal];
[cell addSubview:self.sendButton];
[self.sendButton addTarget:self action:#selector(sendReply:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:field];
cell.accessoryView = nil;
}
}
else
{
cell.accessoryView = nil;
cell.textLabel.text = #"Normal Cell";
}
return cell;
}
Give some unique tag to textfield and button by below way:
///////////////////////////////////////////
////////This is the important part/////////
///////////////////////////////////////////
UITextField *field = [[UITextField alloc] initWithFrame:CGRectMake(14, 6, 245, 31)];
self.sendButton = [[UIButton alloc] initWithFrame:CGRectMake(265, 1, 50, 40)];
[self.sendButton setTitle:#"Reply" forState:UIControlStateNormal];
[self.sendButton setTitleColor:UIColorFromRGB(0x960f00) forState:UIControlStateNormal];
self.sendButton.tag = indexPath.section *1000 + indexPath.row;
[cell addSubview:self.sendButton];
[self.sendButton addTarget:self action:#selector(sendReply:) forControlEvents:UIControlEventTouchUpInside];
field.tag = self.sendButton.tag + 1;
[cell addSubview:field];
cell.accessoryView = nil;
Now on button event,
-(void) sendReply:(UIButton *)sender
{
UITextField *field = [YOOUR_TABLE_VIEW viewWithTag:sender.tag + 1];
//Do you coding here
}
Make a Custom UITableViewCell that has uitextfield and a button on it and make a protocol/delegate of that custom uitableviewcell you've created.. so you can have more control of your code and the event of your button in the future..
check this tutorial: http://www.codigator.com/tutorials/ios-uitableview-tutorial-custom-cell-and-delegates/
cheers
For this,
In cellForRowAtIndexPath: method where you are allocating the send button add one line just to give some identifier to send button as below,
[self.sendButton setAccessibilityIdentifier:[NSString stringWithFormat:#"%d#%d",indexPath.row,indexPath.section]];
Now, in sendReply: method,
//First get the row and section information
NSString *str=[sender accessibilityIdentifier];
NSArray *arr=[str componentsSeparatedByString:#"#"];
//Get the index path
NSIndexPath *iRowId =[NSIndexPath indexPathForRow:[[arr objectAtIndex:0] intValue] inSection:[arr objectAtIndex:1] intValue]];
//get the cell
UITableViewCell *objCell=(UITableViewCell*)[tblviwBasketCell cellForRowAtIndexPath:iRowId];
Now objCell will be the cell in which you have added the button and text view. so get the subviews of objCell and access the textfield to get the text.
As you say, there is a text field in each section. You should set the tag of your UIButton and UITextField same as indexPath.section.
Then, in the target method, use this tag value to get the relevant cell from the relevant section, and iterate over it's subviews to get your textField.
In the target method, you should do something like this:
- (void) sendReply:(id)sender {
int section = [(UIButton*)sender tag];
int row = [myTableView numberOfRowsInSection:section] - 1;//assuming it is the last cell in the section that contains your textField.
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:row inSection:section];
UITableViewCell* cell = [myTableView cellForRowAtIndexPath:indexPath];
for (UIView* vu in cell.subviews) {
if ([vu isKindOfClass:[UITextField class]]) {
NSString* textString = [(UITextField*)vu text];
//perform any tasks you want with the text now
}
}
}
You can simply use viewWithTag:, since it does an iterative search, but all the extra code is to avoid iterating over all the cells before reaching your relevant cell.
In customCell I create some UIButtons and [self addSubview:button];
In UITableView [button addTarget:action:forControlEvents:],When I click button in cell indexPath.row = 0,the indexPath.row = 11 was clicked;
How to get clicked the button and other buttons are not affected?
enter code here
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
{
static NSString *identifier = #"cell";
SettingTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[[SettingTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:identifier]autorelease];
}
if (indexPath.section == 0) {
[cell.customBtn setTitle:#"" forState:UIControlStateNormal];
}
else if(indexPath.section == 1){
if (indexPath.row == 0) {
[cell.customBtn setTitle:#"" forState:UIControlStateNormal];
}
else if(indexPath.row == 1){
[cell.customBtn setTitle:#"" forState:UIControlStateNormal];
}
else{
[cell.customBtn setTitle:#"" forState:UIControlStateNormal];
}
else if (indexPath.section == 2){
if (indexPath.row == 0) {
[cell.customBtn setTitle:#"" forState:UIControlStateNormal];
}
else {
[cell.customBtn setTitle:#"" forState:UIControlStateNormal];
}
}
[cell.WIFIButton addTarget:self action:#selector(openOrCloseButtonClick:)
forControlEvents:UIControlEventTouchUpInside];
return cell;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 7;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == 1) {
return 3;
}
else if(section == 2){
return 2;
}
else if(section == 6){
return 4;
}
else{
return 1;
}
}
enter code here
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
CGFloat originX = IsIOS7?10:15;
UILabel *nameLabel = [[UILabel alloc]initWithFrame:CGRectMake(originX, 7, 150, 30)];
nameLabel.backgroundColor = [UIColor clearColor];
nameLabel.font = [UIFont systemFontOfSize:16];
nameLabel.textColor = [UIColor blackColor];
self.nameLabel = nameLabel;
[self addSubview:nameLabel];
[nameLabel release];
CGFloat rightX = IsIOS7?180:160;
UILabel *fileSizeLabel = [[UILabel alloc]initWithFrame:CGRectMake(rightX - 10, 10, 100,
25)];
fileSizeLabel.backgroundColor = [UIColor clearColor];
fileSizeLabel.font = [UIFont systemFontOfSize:14];
fileSizeLabel.hidden = YES;
self.fileSizeLabel = fileSizeLabel;
[self addSubview:fileSizeLabel];
[fileSizeLabel release];
//This is customButton
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(rightX, 10, 50, 25);
button.backgroundColor = [UIColor grayColor];
self.WIFIButton = button;
[self addSubview:button];
}
Jumping the gun a little on the code, but please consider the following. Add a method that can find the cell where a view appears without using tags.
- (NSIndexPath *)indexPathOfSubview:(UIView *)view {
while (view && ![view isKindOfClass:[UITableViewCell self]]) {
view = view.superview;
}
UITableViewCell *cell = (UITableViewCell *)view;
return [self.tableView indexPathForCell:cell];
}
This assumes you have an outlet called tableView pointing to a table (and it assumes that the parameter is a subview of one of the table's cells). Now, on whatever method runs when a button is pressed:
- (IBAction)myButtonPressed:(id)sender {
NSIndexPath *indexPath = [self indexPathOfSubview:sender];
NSLog(#"button pressed in section %d, at row %d", indexPath.section, indexPath.row);
// ta-da!
}
change static to dynamic cell
static NSString *identifier = #"cell";
to
NSString *identifier = [NSString stringWithFormat:#"cell%d",indexPath.row];
may be its working
I list of contacts from Web Service and display it in contacts 'sectioned' tableView as seen in the screenshot.
Issue is I get same tag values for checkboxes of first row for section A as well as section S. I have sorted one array and displayed in the indexed table view. How to get different tag values depending on indexPath.row irrespective of number of sections displayed. Here's what I tried
In cellForRowAtIndexPath:
UIButton *checkBox;
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
checkBox = [[UIButton alloc]initWithFrame:CGRectMake(7, 8, 30, 30)];
}
else
{
checkBox = [[UIButton alloc]initWithFrame:CGRectMake(15, 13, 30, 30)];
}
//int cnt = 0;
// for (int i = indexPath.section - 1; i > 0 ; i--)
// {
// cnt += [[objectsForCharacters objectForKey:[arrayOfCharacters objectAtIndex:i]] count]; //arrayOfCharachters has char 'A' to 'Z'
// }
//checkBox.tag = cnt + indexPath.row;
[checkBox setImage:[UIImage imageNamed:#"checkBox.png"] forState:UIControlStateNormal];
[checkBox addTarget:self action:#selector(checkBoxClicked:) forControlEvents:UIControlEventTouchUpInside];
[checkBox setTag:indexPath.row];
[cell.contentView addSubview:checkBox];
return cell;
}
-(void)checkBoxClicked:(id)sender
{
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableViewContact];
NSIndexPath *indexPath = [self.tableViewContact indexPathForRowAtPoint:buttonPosition];
UIButton *tappedButton = (UIButton*)sender;
NSLog(#"Tag number = %d", [sender tag]);
if([tappedButton.currentImage isEqual:[UIImage imageNamed:#"checkBox.png"]])
{
[sender setImage:[UIImage imageNamed: #"checkBoxMarked.png"] forState:UIControlStateNormal];
if(indexPath != Nil)
{
NSString *finalIntId = [mutableArrayOfIds objectAtIndex:indexPath.row]; // store check box ids in mutableArrayOfIds
NSLog(#"Tagged checked button id = %#", finalIntId);
[arrayOfIds addObject:finalIntId];
}
//NSString *finalIntId = [mutableArrayOfIds objectAtIndex:tappedButton.tag];
//NSString *finalIntId = [mutableArrayOfIds objectAtIndex:indexPath.row];
}
else
{
[sender setImage:[UIImage imageNamed:#"checkBox.png"]forState:UIControlStateNormal];
NSLog(#"UnChecked");
//[arrayOfIds removeObjectAtIndex:tappedButton.tag];
}
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if ([arrayOfCharacters count] == 0)
{
return #"";
}
return [NSString stringWithFormat:#"%#", [arrayOfCharacters objectAtIndex:section]];
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
NSArray *toBeReturned = [NSArray arrayWithArray:
[#"A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|#"
componentsSeparatedByString:#"|"]];
return toBeReturned;
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
NSInteger count = 0;
for (NSString *character in arrayOfCharacters) {
if ([character isEqualToString:title]) {
return count;
}
count ++;
}
return 0;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [arrayOfCharacters count];
//return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//return [mutableArray count];
return [[objectsForCharacters objectForKey:[arrayOfCharacters objectAtIndex:section]] count];
}
you are setting the same tag value for all sections which have same row.
The indexPath has two properties, {section,row}.
Lets say section A has two rows,
for row1 -> indexPath.section=0, indexPath.row=0;
for row2-> indexPath.section=0, indexPath.row=1;
Lets say section S has two rows,
for row1 -> indexPath.section=1, indexPath.row=0;
for row2-> indexPath.section=1, indexPath.row=1;
So, for row1 of section A and row1 of section S, you are setting the same tag value which is 0.There is your problem.
Try setting tag value like below.
button.tag = indexPath.section*1000 +indexPath.row;
when retrieving the section and row,
NSInteger section = (button.tag)/1000;
NSInteger row = (button.tag)%1000;
Try this...
- (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:CellIdentifier];
}
UIButton *checkBox =[[UIButton alloc] initWithFrame:CGRectMake(280, 10, 50, 44)];
checkBox.backgroundColor =[UIColor orangeColor];
[checkBox addTarget:self action:#selector(checkBoxClicked:event:)forControlEvents:UIControlEventTouchUpInside];
[checkBox setTag:indexPath.row];
[cell.contentView addSubview:checkBox];
return cell;
}
- (void)checkBoxClicked:(id)sender event:(id)event
{
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:self.tv]; //here tv is TableView Object
NSIndexPath *indexPath = [self.tv indexPathForRowAtPoint: currentTouchPosition];
NSLog(#"value of indePath.section %d ,indexPath.row %d",indexPath.section,indexPath.row);
}
This is happening because you are assigning tag to buttons INDEPENDENT of sections.
Both of First Row of Sections A & S have row = 0. so Tag Assigned to their respective button is 0. You should assign them Keeping reference to your sections.
i would suggest to assign accessibility hint with comma separated form containing Section,Row.
And in your method
-(void)checkBoxClicked:(id)sender
{
//pick string from comma separated form. 1st is your section, 2nd is row.
}
second option is Do what ever your doing and implement your Button method like this.
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
if (indexPath != nil)
{
... indexpath.section is your section , index path.row is your row.
}
There is Third option as well.
in cellforRowAtIndexpath assign your Button a title
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
[btn setTitle:<#Your Row#> forState:UIControlStateDisabled];
[btn setTag<#Your Section#>];
so upon Receiving in your Button Method you can have both Section (Tag) and Row (Title for Disabled state).
-(void)checkBoxClicked:(id)sender { [button titleForState:UIControlStateDisabled]; // your Row
button.tag //your Section }
Try this!
Each section you may know the count of section right, then add count of individual row.
[[fieldTitlesList objectAtIndex:indexPath.section - 1] count] + indexPath.row
Where fieldTitlesList is the array of your sections.
I added the following code which solved my issue
NSInteger rowNumber = 0;
for(NSInteger i = 0; i < indexPath.section ; i++)
{
rowNumber += [self tableView:self.tableViewContact numberOfRowsInSection:i];
}
rowNumber += indexPath.row;
[checkBox setTag:rowNumber]; //checkBox is UIButton in cellForRowAtIndexPath
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