As I understand it, the UITableViewCellAccessoryTypeCheckmark appears when the row is tapped/untapped.
However, I would like to make an accessory that is always visible. Like a Checkbox or something of the sort. This is because i want to display additional information if the row is selected but if the Checkbox at the right end of the row is tapped, a tick should appear in it.
Sorry if I was not very clear. Please ask me for any clarifications.
Thanks!
You have to create your custom accessory view. In that view you add two UIImageView, and give a tag for the checkbox.
On create:
#define CHECKBOX_TAG 123
UIView *customAccessoryView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 60, 30)] autorelease];
UIImageView *otherInfo = [[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)] autorelease];
UIImageView *checkbox = [[[UIImageView alloc] initWithFrame:CGRectMake(30, 0, 30, 30)] autorelease];
checkbox.tag = CHECKBOX_TAG;
[customAccessoryView addSubview:otherInfo];
[customAccessoryView addSubview:checkbox];
cell.accessoryView = customAccessoryView;
On display, if selected, set the checkbox hidden to NO:
UIImageView *checkbox = [cell.accessoryView viewWithTag:CHECKBOX_TAG];
if(selected){
checkbox.hidden = NO;
}else{
checkbox.hidden = YES;
}
You can achieve this by using button.Create a button in cell with unchecked checkbox image and when user click on this button change the image of the button to check.
If you want a UIKit use accessoryType property of a UITableViewCell.
#property(nonatomic) UITableViewCellAccessoryType accessoryType
If you really want a custom one use accessoryView.
#property(nonatomic, retain) UIView *accessoryView
Make a button and add it to your acceessoryView: and use it like a check box...
this will resolve your problem
Related
Hi all I am trying to add a UITextField to my cameraOverlay. I am getting it to show up on my camera view, but it is not editable. Its not responding at all. What approach do I need to take to get it to repsond?
I have looked at this questions, but do not understand how to set a transparent View Controller on top of my cameraOverly.
Suggestion for camera overlay
Thanks in advance!
Steps should be:
Create your picker.
Create an empty view with clearColor background.
Add your textfield with addSubview: to the view in step 2.
Set cameraOverlayView to the view created in step 2.
Present your picker.
In code:
//self.picker and self.textField being your UIImagePickerController and UITextField instances.
emptyView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)]; //This frame will make it fullscreen...
emptyView.backgroundColor = [UIColor clearColor];
[emptyView setAlpha:1.0]; //I think it is not necessary, but it wont hurt to add this line.
self.textField.frame = CGRectMake(100, 100, self.textField.frame.size.width, self.textField.frame.size.height); //Here you can specify the position in this case 100x 100y of your textField preserving the width and height.
[emptyView addSubview:self.textField];
self.picker.cameraOverlayView = emptyView; //Which by the way is not empty any more..
[emptyView release];
[self presentModalViewController:self.picker animated:YES];
[self.picker release];
I typed the code here myself so it could have some typo, Hope it helps!
I am an iOS development newbie. I have a settings screen which is a UITableView. I want to add some explanation to it. I am using the following code to do it, but it skews up the text completely. Any idea what I am doing wrong?
UILabel *subjectLabel = [[UILabel alloc] initWithFrame:CGRectMake(0,0, 300, 175)];
subjectLabel.font = [UIFont systemFontOfSize:16.0];
subjectLabel.numberOfLines = 0;
subjectLabel.font = [UIFont fontWithName:#"Arial Rounded MT Bold" size:(10.0)];
subjectLabel.backgroundColor = [UIColor clearColor];
//bodyLabel.textAlignment = UITextAlignmentLeft;
subjectLabel.text = #"mytext";
settingTableView = [[[UITableView alloc] initWithFrame:CGRectMake(0,0, 320, 370) style:UITableViewStyleGrouped] autorelease];
settingTableView.dataSource = self;
settingTableView.delegate = self;
[settingTableView addSubview:subjectLabel];
[self.view addSubview:settingTableView];
A tableViewHeader is a UIView which is set as the tableViewHeader property of a tableView. If you want to have a UILabel in a header view, make a separate UIView (either in code, or in a nib), and set it as the tableView.tableHeaderView property. More information can be found here: TableView Reference. Hope that helps!
create a view in your view controller and add your lable to that and bind it ...
IBOutlet UIView *headerView1;
and add this code
settingTableView.tableHeaderView = headerView1;
Suggestion1 : You could have create a separate view which contains your UILabel and place above the UITableView and place your tableView y position would be from the height of the UIView.
Remark : This is useful because when you scroll the tableView the default header will be stick to top.
Suggestion2 : you can use viewForHeaderInSection delegate method. where you can create a view and add the UILabel. viewForHeaderInSection returns the UIView, which you can return your view which contains the UILabel
Remark : when you scroll the tableView the default header will move along with your tableView
I have UISearchBar on UITableView's header, I want to add UILabel above UISearchBar. UILabel is hidden for the first time, when User scroll down the TableView, UILabel will appear. It's done in WhatsApp, in the Contacts' tab.
What is the best way to do this?? Any help will be appreciated.
Regards
One way is to add the UILabel, UISearchBar and UITableView in a UIView.
Otherwise, add the UILabel in first row, search bar in the second row and go on...
Not able to test this right now but I think:
theHeader = [[UIView alloc] initWithFrame:CGRectMake(0, 0 - HEADER_HEIGHT, 320, HEADER_HEIGHT)]
headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, HEADER_HEIGHT)];
headerLabel.textAlignment = UITextAlignmentCenter;
Also don't forget to add the subview to the header:
[theHeader addSubview:headerLabel] and to put a height for your header either within CGRectMake or defined (e.g. #define HEADER_HEIGHT 52.0f)
Let me know if it worked!
I am new to iPhone development and I am currently working on a simple RSS reader app. The problem I am having is that I need to reposition the textLabel inside the UITableViewCells. I have tried setFrame or setCenter but it doesn't do anything. Does anyone know what I need to do inside the tableView:cellForRowAtIndexPath: method to reposition the textLabel at the top of the cell (x = 0, y = 0)?
Thank you
PS: The UITableViewCell is referenced by a variable called cell. I have tried [cell setFrame:CGRectMake(0, 0, 320, 20)] with no success.
You can create a subclass for UITableViewCell and customize de textLabel frame. See that answer: Labels aligning in UITableViewCell. It's works perfectly to me.
It's my subclass
#import "UITableViewCellFixed.h"
#implementation UITableViewCellFixed
- (void) layoutSubviews {
[super layoutSubviews];
self.textLabel.frame = CGRectMake(0, 0, 320, 20);
}
#end
It's my UITableViewControllerClass:
UITableViewCellFixed *cell = (UITableViewCellFixed *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCellFixed alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
You may try indentationLevel, separatorInset and other content indentation properties of UITableViewCell object.
Seems I solved my own problem. Here's some code, in case someone runs into the same problem:
UILabel *ttitle = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 20)] autorelease];
ttitle.font = [UIFont boldSystemFontOfSize:13];
ttitle.textColor = [UIColor blackColor];
ttitle.textAlignment = UITextAlignmentLeft;
[ttitle setText:[[stories objectAtIndex: storyIndex] objectForKey: #"title"]];
[cell.contentView addSubview:ttitle];
The idea is to create your own label object, because the textLabel is automatically positioned and can't be moved around.
Cheers.
The reason the original poster's code doesn't work is that it appears that the frame of the textLabel is set after the UITableViewCell has been returned from your delegate method.
I noticed that I can successfully alter many properties of the textLabel, such as the text alignment, color, font, etc, but altering the frame has no effect and when I print the frame to the debugger later (like on select), the frame isn't what I set. Therefore, I conclude that the UIKit framework is altering the frame of the textLabel after it is returned from the delegate method. No doubt this is likely done because Apple engineers wanted to make sure that your text was drawn to the screen, so they measure it and alter the frame so that it will fit. They probably figured that people such as ourselves who wanted to alter the position of the text would be able to do so by subclassing, or simply adding another UILabel (or whatever) as a subview. A novice developer might have a very hard time if his or her text didn't show up in the label or was truncated because they didn't adjust the frame.
In my case, I wanted the text to be center horizontally, to be a specific color/font/size, and to be slightly higher vertically in the cell. Being too lazy to subclass this, I first tried altering the frame. When that didn't work, I tried googling the answer (found this post).
My final solution was to set the numberOfLines property to 0 and add some trailing carriage returns to my text. Now THAT is lazy.
In Swift 3 it would be
override func layoutSubviews() {
super.layoutSubviews()
self.textLabel?.frame.origin.x = 50
}
I'd like to add a button to a table cell. The "Delete Event" in the calendar app inspired me... (a similar case is "Share Contact" in contacts)
As of now there's
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//..yadayadayada
cell = [tableView dequeueReusableCellWithIdentifier:#"buttonCell"];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:#"buttonCell"] autorelease];
}
UIButton *button = [UIButton buttonWithType:UIButtonTypeInfoDark];
[button setBackgroundColor:[UIColor redColor]];
button.titleLabel.text = #"Foo Bar";
[cell.contentView addSubview:button];
which produces a button, indeed. It doesn't look yet how it's supposed to (it's obvious I've never dealt with buttons in iPhone, yet), but is this at least the right approach?
The way you have it now each time a cell is shown you're allocating a button, setting its value, and adding it to the cell's contentView. When the cell gets reused (via dequeueReusableCellWithIdentifier) you'll be creating another new button, adding it to the cell (on top of the old one) etc. The fact that it's gone through addSubview but no explicit release means each button's retain count will never go to zero so they'll all stick around. After a while of scrolling up and down the cell will end up with hundreds of button subviews which probably isn't what you want.
A few tips:
Never allocate stuff inside a cellForRowAtIndexPath call unless it's done when dequeueReusableCellWithIdentifier is returning nil and you're initializing the cell. All other subsequent times you'll be handed back the cached cell that you will have already set up so all you have to do is change the labels or icons. You're going to want to move all that button allocation stuff up inside the if conditional right after the cell allocation code.
The button needs to have a position and also a target set for it so it'll do something when tapped. If every cell is going to have this button a neat trick is to have them all point to the same target method but set the button's tag value to the indexPath.row of the cell (outside the cell allocation block since it varies for each cell). The common tap handler for the button would use the tag value of the sender to look up the underlying data in the dataSource list.
Call release on the button after you've done an addSubview. That way the retain count will fall to zero and the object will actually get released when the parent is released.
Instead of adding the button via addSubview, you can return it as the accessoryView for the cell so you don't have to worry about positioning it (unless you're already using the accessoryView for something else -- like disclosure buttons).
I took a different approach to creating an equivalent to the 'Delete Event' button in the Calendar app. Rather than add a button as a subview, I added two background views (red and darker red, with nice gradients) to the cells and then rounded off the corners and set the border to grey.
The code below creates a re-usable cell (in the usual fashion). The two images referred to ('redUp.png' and 'redDown.png') were taken from a screenshot of the calendar's 'Delete Event' button. (That seemed quicker than creating the gradients programmatically.) There's scope for a bit more fine tuning to get it even closer to the Calendar's 'Delete Event' appearance, but this is pretty close.
The button's action is triggered by the tableView delegate method tableView:didSelectRowAtIndexPath: method.
// create a button from a table row like the Calendar's 'Delete Event' button
// remember to have an #import <QuartzCore/QuartzCore.h> some above this code
static NSString *CellWithButtonIdentifier = #"CellWithButton";
UITableViewCell *cell = [self dequeueReusableCellWithIdentifier:CellWithButtonIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellWithButtonIdentifier] autorelease];
[[cell textLabel] setTextAlignment: UITextAlignmentCenter];
UIImageView* upImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"redUp.png"]];
UIImageView* downImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"redDown.png"]];
[cell setBackgroundView: upImage];
[cell setSelectedBackgroundView: downImage];
[[upImage layer] setCornerRadius:8.0f];
[[upImage layer] setMasksToBounds:YES];
[[upImage layer] setBorderWidth:1.0f];
[[upImage layer] setBorderColor: [[UIColor grayColor] CGColor]];
[[downImage layer] setCornerRadius:8.0f];
[[downImage layer] setMasksToBounds:YES];
[[downImage layer] setBorderWidth:1.0f];
[[downImage layer] setBorderColor: [[UIColor grayColor] CGColor]];
[[cell textLabel] setTextColor: [UIColor whiteColor]];
[[cell textLabel] setBackgroundColor:[UIColor clearColor]];
[cell setBackgroundColor:[UIColor clearColor]]; // needed for 3.2 (not needed for later iOS versions)
[[cell textLabel] setFont:[UIFont boldSystemFontOfSize:20.0]];
[upImage release];
[downImage release];
}
return cell;
Yes, this is generally the correct approach.
A tip:
Set the callback for your button events, so that it actually does something when clicked.
[myButton addTarget:self action:#selector(whatMyButtonShouldDo:)
forControlEvents:UIControlEventTouchUpInside];
EDIT: Adjusted code for using a system button, which renders a lot of what I had written uneccessary.
Yes, you are on the right track, that's the easiest way to add a subview to a cell (the other is subclassing a UITableViewCell).
Check the Apple guide for more info.
To avoid positioning and memory management hassles you can create a specialized cell class and link to a XIB. That sounds like the cleanest approach to me. Here is the link:
http://icodeblog.com/2009/05/24/custom-uitableviewcell-using-interface-builder/