Updating/Removing UILables from View - iphone

I'm creating some UILabels in my UIView, filling them with data, adding them to view, and releasing them.
UILabel *speed = [self scrollLabel:#"some Text" x:455.0f y:75.0f];
[scrollView addSubview:speed];
[speed release];
The method:
- (UILabel *)scrollLabel:(NSString *)text x:(float)x_ y:(float)y_ {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(x_, y_, 300.0f, 20.0f)];
[label setText:NSLocalizedString(text,#"")];
[label setFont:[UIFont fontWithName:#"Helvetica" size:14]];
[label setTextColor:[UIColor colorWithRed:255.0 green:255.0 blue:255.0 alpha:1.9]];
[label setBackgroundColor:[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0]];
return label;
}
I got a button, where the user can reload the data of the uilabels. I'm removing the parent view of all these labels from superfiew, generating the new data and doing the method where the labels are set, again.
The problem is, the old UILabels are still existing, so my question is, whats the best way to remove this special labels?
I made a loop and removed all subviews, the problem is, I also got some other subviews in there, which I don't want to delete.
Another question: Is there a better way to setup font-styles for multiple Labels?

I would suggest adding all the labels in a specific UIView, let's call it labelHolderView. Then every time you want to remove them, just iterate through all of its children and call removeFromSuperview for each one.
If you only want to remove specific UILabels, please provide more info as to which ones they should be.
One thing I would suggest for your code above: your - (UILabel *)scrollLabel:(NSString *)text x:(float)x_ y:(float)y_ method should return an autoreleased UILabel. So its last line should be return [label autorelease];. If you want to return a retained object, add new/copy/retain in the method's name, so that you know that the returned object is being retained every time you call it.
Consequently, you don't need to release the label after you add it to the UIView. This does not affect your specific program, but it's good to get in the habit of doing it this way so that you don't mess your retains/releases in the future.

Related

Custom UIAlertView iphone

I have a problem .. I used this http://kwigbo.com/post/318396305/iphone-sdk-custom-uialertview-background-color to create my own custom UIAlertView.
I do not know why but this will not work:
UILabel *theTitle = [theAlert valueForKey:#"_titleLabel"];
[theTitle setTextColor:[UIColor redColor]];
UILabel *theBody = [theAlert valueForKey:#"_bodyTextLabel"];
[theBody setTextColor:[UIColor blueColor]];
the color of the title does not change .. the color of texbody it's ok.
How can I customize the buttons?
Hi Achieved same thing using custom UIAleartView.
Make a custom view as follows.
UIView *tempView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 5.0f, 262.0, 49)];
tempView.backgroundColor = [UIColor clearColor];
UILabel *lblTitle = [[UILabel alloc] initWithFrame:CGRectMake(12, 0, 262.0, 49)];
lblTitle.font = [UIFont fontWithName:#"Arial" size:22.0f];
lblTitle.textColor = [UIColor whiteColor];
lblTitle.textAlignment = UITextAlignmentCenter;
lblTitle.text = #"Subscribe";
lblTitle.backgroundColor = [UIColor clearColor];
[tempView addSubview:lblTitle];
alreadySubscriber = [[UIButton alloc] initWithFrame:CGRectMake(12, 260, 262.0, 50)];
alreadySubscriber.layer.cornerRadius = 25.0f;
[alreadySubscriber setTitle:#"Already a subscriber" forState:UIControlStateNormal];
[alreadySubscriber setBackgroundImage:[UIImage imageNamed:#"BTN0.png"] forState:UIControlStateNormal];
[alreadySubscriber setBackgroundImage:[UIImage imageNamed:#"BTN1.png"] forState:UIControlStateSelected];
[tempView addSubview:alreadySubscriber];
Insert this in UIAleartView
[self insertSubview:tempView atIndex:0];
[self setNeedsLayout];
Override layoutsubview as you have already done push all other controls down equal to view Height.
-> basically matter is to hide UIAleartView's title behind a label.
Not sure exactly what your issue might be, but we faced a similar situation when trying to workout a custom UIAlertView, so might be similar.
The custom solution in the link you provided appears to manipulate the alerts title and background by accessing the subview hierarchy and 'guessing' which subview might be which. (I may be wrong, didn't look through it in detail) The problem with this approach is that it'll work fine for one OS version, but in subsequent OS versions, Apple may restructure this subview hierarchy in some manner, and this 'guesswork' is no longer accurate. (i.e. the subview assumed to be the background image may not be).
This could be the case, seeing that posted link is an year old. If you're proceeding with this, you may have to review the subview hierarchy to see if they still match up.
I believe, that you can find proper solution without using standart tools, which are present in UIAlertView. But in this case, you application will be not approve for AppStore. That way, I strongly recommend you, avoid to using custom buttons in AlertView.
Maybe, you will find solution using UIActionSheet instead UIAlertView . It's more customizing.
If #"_titleLabel" is part of the UIAlertView hierarchy (which looks likely given the _ prefix), I can't recommend your approach.
Apple might some day change the key strings: If #"_titleLabel" ever changes, say to #"_titleLabelView", you're sunk and you might never know that you're sunk. This might even be grounds for rejection, I wouldn't know.
It's better to start out from scratch with your own custom view, subclassing UIView. Only then can you guarantee that this will be stable from OS to OS. On top of this, the time you lose trying to find a shortcut will be positively spent constructing some thing durable.

How to add Activity Indicator as subview to UIButton?

Can we add activity indicator as subview to UIButton?
If yes then plz tell me how to do that?
I used [button addSubview:activityIndicator];
Not working...
I found that adding a UIActivityIndicatorView to a UIButton was a really useful method to allow users to know something is happening without having to use the MBProgressHUD (I think the HUD is really good but should not be used in all situations.
For this reason I created two functions:
I have already allocated my UIButton so it is a class variable called _confirmChangesButton
I then create my activity indicator, set its frame (taking into account the button size) and then adding the indicator is easy.
- (void)addActivityIndicatorToConfirmButton {
// Indicator needs to be in the middle of the button. So half the screen less half the buttons left inset less half the activity indicator size
CGRect rect = CGRectMake([UIScreen mainScreen].bounds.size.width/2 - 10 - 15, 5, 30, 30);
UIActivityIndicatorView * activity = [[UIActivityIndicatorView alloc] initWithFrame:rect];
activity.hidesWhenStopped = YES;
[_confirmChangesButton setTitle:#"" forState:UIControlStateNormal];
[_confirmChangesButton addSubview:activity];
[activity startAnimating];
}
Having a removal function is also useful if you are using blocks. It might be that the completion task comes back with a failure and so we want to remove the indicator and change the title back. In this function we need to make sure to remove the indicator and not the button label which is the other subview on this button.
- (void)removeActivityIndicatorFromConfirmButton {
UIActivityIndicatorView * activity = _confirmChangesButton.subviews.lastObject;;
[activity removeFromSuperview];
[_confirmChangesButton setTitle:#"Confirm Change" forState:UIControlStateNormal];
}
I found that using these two you can create a much better user experience letting the user know what is going on when they press buttons.
Hope this helps
Use the below code below to add acitivity indicator a button or any uiview object
UIActivityIndicatorView *aView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
aView.frame = CGRectMake(0, 0, {yourButton}.frame.size.width, {yourButton}.frame.size.height);
aView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.7];
[{yourButton} addSubview:aView];
[aView startAnimating];
Hope this will help..
I don't think it's possible to add a view to a button. UIButton have this method because it's inherited from UIVIew.
The real question is : why do you want to add an activity indicator on a button and not elsewhere ?
did you do [activityIndicator startAnimating]; ALso as u are using it in a tableview just check if the tags are set properly

Title for section in UITableView - remove text shadow?

I have a grouped UITableView with black background color.
Thus the gray section headers with the white drop shadows are unreadable.
Next thing to know, the section height varies depending on language and section.
How to solve this the most easy way ?
If I implement viewForHeaderInSection I also need to implement heightForHeaderInSection, but the height varies (several sections with different title and different language => different text length/view height)
You need to dynamically determine the height of the cell, and set your label so that it autosizes itself.
Hope this link will be helpful to you.
All the best.
I had the same issue in 6.1. This worked for me:
- (void) viewDidLoad {
[super viewDidLoad];
[self.tableView setBackgroundView:nil];
self.tableView.backgroundColor = [UIColor blackColor];
[[UILabel appearance] setShadowColor:[UIColor clearColor]];
[[UILabel appearance] setTextColor:[UIColor lightGrayColor]];

UIButton in UITableView cell like "Delete Event"

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/

can i use highlighted the table view cell without default blue color in objective c?

I doing a project where i need to use highlighted table view color not default.
Of course you can.
There are two methods to achieve this:
Use UITableViewCell's selectedBackgroundView and selectedTextColor properties
Subclass UITableViewCell and implement the drawInRect and setSelected:animated: methods
The latter option gives you more flexibility and much better performance, but it might be slightly harder if you haven't used CoreGraphics before.
UPDATE In response to the OP's comment:
Here's how you can use the selectedBackgroundView property:
UIView *bgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 60)];
[bgView setBackgroundColor:[UIColor redColor]];
[cell setSelectedBackgroundView:bgView];
[bgView release];
I haven't tried this myself, but it should work.
Try referring to this demo - maybe you could have a look at it and get some help.