How can I remove a shadow in iPhone - iphone

I am using the standard way of making shadows from a button programmatically, but I would like to shadow to no longer exist after I am done with the button. I could set opacity to 0, but would the shadow still exist and if so would it still tax the system. thanks
this gives an error
tempButton.superview.layer.shadowOffset = nil;
tempButton.superview.layer.shadowRadius = nil;
tempButton.superview.layer.shadowOpacity = nil;

I usually do the following to be safe.
[[tempButton layer] setShadowOpacity:0.0];
[[tempButton layer] setShadowRadius:0.0];
[[tempButton layer] setShadowColor:nil];
Quartz is highly optimized and will not waste any time rendering if it doesn't have to.

I would just remove the button, and replace it with an identical (but non-shadowed) button. Or keep both around and hide/unhide one of them. Sometimes it's easier to create a new UI object than munge around with an existing one.

Related

iOS views - how to remove excessive shadow?

I have a UIViewController that I'm nesting inside another UIViewController (iOS 4.3+),
it is displayed just fine except one thing - a lot of excessive shadow.
I have tried removing it with setShadowRadius etc, but no luck..
This is the code I use to create it:
RDPreviewViewController* preview = [[[RDPreviewViewController alloc] initWithNibName:#"RDPreviewViewController" bundle:[NSBundle mainBundle]] autorelease];
[preview.view.layer setShadowOpacity:0.0];
[preview.view.layer setShadowRadius:0.0];
[preview.view.layer setColor:nil];
[preview.view setFrame:CGRectMake(0, 100, 320, 264)];
[self.mainView addSubview:preview.view];
And here's the result:
How do I remove it?
I suspect - and this is a theory - that given what you've said that somehow your PNG image with the subtle shadow is being loaded multiple times. This is why your shadow appears much darker than you're expecting - several identical PNGs are being overlaid on top of each other.
The reason I think this is the case is that judging from the code you've posted you're not programatically applying a shadow, and views do not have a shadow by default. Of course, perhaps you are adding a shadow in your code elsewhere, but based on my own experience I think it looks as if somehow the same view (your image view) is getting added multiple times.
It might be helpful if you shared more of your code, if possible.

IOS: Using A Pattern Image As A Background -Memory Leak

OK. I'll be looking for the answer, and may find it myself. I have a nasty habit of answering my own questions.
In any case, I have an app that is designed to be "skinned" fairly easily. As part of that, I have sequestered methods in a static class that is specific to variants. These static methods feed the main app images, colors and settings specific to the variant. The .h file is common to the main app, but the .m file is specific to the variant.
I like to use the ability to send an image as a background (which is automagically tiled), so the interface file specifies the routine as returning a UIColor, like so:
+ (UIColor *)meetingDetailBackgroundColor;
But the implementation file loads an image file, and returns that, like so:
+ (UIColor *)meetingDetailBackgroundColor
{
return [UIColor colorWithPatternImage:[UIImage imageNamed:#"DarkWeave.png"]];
}
Which is used in context, like so:
[[self view] setBackgroundColor:[BMLTVariantDefs meetingDetailBackgroundColor]];
NOTE: Edited to restore the original simple code I used.
Now, the issue is that I sometimes (not always) get a leak.
I'm sure that I'm doing something hinky here. I'm just not sure what.
Any ideas?
BTW: This is an ARC program, running on IOS 5. I'm new to ARC, but I think this is the way I'm supposed to do it.
UIColor colorWithPatternImage is buggy, do not use it. My experience is that it tends to greatly cripple performance on the device but not in the simulator. Anything like scrolling or animation on top of it tends to get slow. I'm not sure whether this really qualifies as a leak, I'm not seeing App being killed because RAM ran out. But if you profile the app, you will see that the app runs much slower with UIColor colorWithPatternImage enabled and drawing something.
Eventually I created a subclass of UIView, and did something like this:
- (void)drawRect:(CGRect)rect
{
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextSetBlendMode(c, kCGBlendModeCopy);
CGContextDrawTiledImage(c, CGRectMake(0, 0, bkgnd.size.width, bkgnd.size.height), bkgnd.CGImage);
}
This will tile the image. I then either use self.tableView.backgroundView or [self.view insertSubview:bkgnd atIndex:0] to make it a background. It runs much faster on the device, and causes zero memory leaks.
The best way to initilise your shared colour is like this:
+ (UIColor *)color
{
static UIColor *color;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
color = [[UIColor alloc] init...];
});
return color;
}
It is thread safe and only initialises the colour once. That way there is no way that you can leak the colour.
OK. I addressed this, but I did not fix it.
I punted.
It is, indeed, Instruments making wild guesses. There was nothing wrong with the way I specified the color (however, I liked one of the suggestions here, and redid my color spec that way).
It seems to be a very small leak, buried somewhere deep in the bowels (and I mean that literally) of MapKit. There seems to be absolutely nothing that I can do to resolve it.
After several hours of brick wall/neocortex interaction, I just gave up, and made the screen controller object reusable. I simply keep it hanging around, and change the contents to suit the meeting being inspected.
That puts off the leak until the app closes.
I am such a wimp.
Thanks.

CA animation of a UIView inside a UITableView. Like the one on iTunes

I've been checking this site for many of my questions before but this is the first time I actually have to ask someting, so I hope I can make myself clear enough.
I have an App which is nearly finish. The main functionallity is in up and running. I'm only concern in making the whole App visually appealing. The App is maninly a database wich scientifical relevant data. I want the user to be able to store custom data in the DB and to do that I've created a "contact-like" view where the user can save some data. The view contains a table and inside this table, the cell have UITextFields. After entering the data, when the user presses a button, I want to animate the content of the textField to a cabinet-like icon. Very much like when you purchase something in the iTunes on a iOS device.
I've been able to do that animation in a "static" view (not a UITableView), playing around with starting point, end point and so on is a bit of a pain in the neck, but doable after all.
I'm doing the animation in a not really conventional way, I think, but actually very effecive. On the press of the button I create a UILabel, I set the text as the text of the textField and then I use viewAnimationWithDuration block to animate the label. Inside the block I also use Core Animation to animate the layer of the label over a path. Again, not conventional, but straight forward.
The problem I'm having is that I'm not able to create the label over the textField since it is in a UITableView. Mainly the problem is to know the position (or frame, or bounds, or position. I'm really confused already) of the textField and hence, the starting position of the path.
The code I'm using is as follows:
-(IBAction)saveCustom:(id)sender{
UILabel *imageViewForAnimation = [[UILabel alloc] initWithFrame:CGRectMake(l1, l2, l3, l4)];
imageViewForAnimation.text=label.text;
imageViewForAnimation.alpha = 1.0f;
imageViewForAnimation.backgroundColor=[UIColor clearColor];
imageViewForAnimation.textColor=[UIColor blackColor];
imageViewForAnimation.adjustsFontSizeToFitWidth=YES;
[self.view addSubview:imageViewForAnimation];
[UIView animateWithDuration:10.0
delay:0.0
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
// Set up path movement Core Animation begins
CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:#"position"];
CGPoint endPoint = CGPointMake(310, 380); // final point
CGMutablePathRef curvedPath = CGPathCreateMutable();
CGPoint rootViewPoint = [imageViewForAnimation convertPoint:imageViewForAnimation.center toView:taula];
CGPathMoveToPoint(curvedPath, NULL, rootViewPoint.x, rootViewPoint.y); // initial point
CGPathAddCurveToPoint(curvedPath, NULL, 100, 100, 100, 100, endPoint.x, endPoint.y);
pathAnimation.path = curvedPath;
CGPathRelease(curvedPath);
pathAnimation.fillMode=kCAFillModeForwards;
pathAnimation.removedOnCompletion=NO;
pathAnimation.duration=10.0f;
pathAnimation.delegate=self;
[imageViewForAnimation.layer addAnimation:pathAnimation forKey:#"savingAnimation"];
[imageViewForAnimation release];
//Core Animation ends
imageViewForAnimation.transform=CGAffineTransformMakeScale(0.60, 0.60);
// imageViewForAnimation.alpha=0.2;
}
completion:^(BOOL finished){
[imageViewForAnimation removeFromSuperview];
} ];
}
Any help on how to proceed will be much appreciated.
Thanks in advance!
UPDATE:
I went to the Apple Tech Talks in Berlin. In the labs they got, I asked an engineer about that. He wondered that the code I showed him didn't work. I emailed to him and he'll be back to me.
The key thing is to transform the coordinates from the table, to the view.
A UITableView shows a number of UITableViewCells. If you want to customize the controls displayed in a cell, you can add additional controls to the contentView of a UITableViewCell. Depending on how complicated your needs are, you would do this in the UITableViewDelegate or by subclassing UITableViewCell. Just be aware that adding subviews to contentView will likely interfere with the built-on controls (e.g. textLabel or detailTextLabel).
To position your additional controls or animation effects, you can check the bounds of the cell's contentView. Add your controls as subviews of contentView, animate them, and don't forget to remove them when you no longer need them.
Seems pretty conventional animation to me. And yes, effective.
As to a solution, you just need to save some state info when the user requests a save. And draw your animation label on top of the table. Should be no major problems there as long as you have a view available, super view of the table maybe?
Beyond that, how is your UI setup with respect to this table? How is the save custom activated (does the save all data or a specific field, do you have selected cell which you can access to pull the needed origin of your animation data)?
Also, don't forgot to release your UILabel after you add it as a subview, you are leaking it in the code above.

Which UI object to do this?

I have seen many times waiting panels (panels with a uiactivityindicatorview) black/dark with some transparency and white labels.
Like this one :
I guess it is a standard element.
Where can I find it?
Try This. it's the best solution I came across to show the activity. MBProgressHUD
MBProgressHUD looks nice. You might want to check out http://code.google.com/p/toast-notifications-ios/ too.
There's no iOS component that does this.
If you don't want to include an external library just for this one component then you can do it using UI components.
/* Warning, typed from memory */
// Create the UIView that's the background
UIView *pleaseWaitView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 80)];
[pleaseWaitView setBackgroundColor:[UIColor colorWithWhite:0.5 alpha:0.5]];
[[pleaseWaitView layer] setCornerRadius:5.0f];
// And create an activity indicator
UIActivityIndicator *i = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
[i startAnimating];
[pleaseWaitView addSubview:i];
[i release];
// Add it to the main view (in the middle)
[pleaseWaitView setCenter:CGPointMake(self.view.bounds.size.width/2, self.view.bounds.size.height/2)];
[self.view addSubview:pleaseWaitView];
You can add a UILabel with whatever text you want (in your case, 'Authenticating') in the same way as you added the activity indicator.
The tricky part is setting the corner radius - you will probably need this at the top of your .m file :
#import <QuartzCore/QuartzCore.h>
NB You can do this in interface builder as well if you want (apart from the corner radius bit!) ;)
I answered a question that included an overlay like this. I included the code and the overlay image you need to do it with. Take a look at this answer and take a look at the screen shot it created. I use this overlay as I send email in the background so you will want to edit the code to do your function but the overlay code is already in place.
Locking the Fields in MFMailComposeViewController
Happy Coding!
Check out DSActivityView. I've successfully used it in a few of my projects.
As by now there is no standard UIElement for that in iOS.
But checkout this library:

setting image to button -> take up lots of memory ? what should i do then

basically im running my apps with instruments and found out that by just setting a background image to the UIButton, it takes up 6mb of data(which i do not want in case low-memory warnings). i read around and found out that since the button has been assigned the image, it retains it(and the memory).
How should i code it then?My current codes are as below. Btw im new to iPhone development so please tell me what to do.
btw this button would just bring me to another view. is there anyway to release the memory that was allocated to this image?
.m file
-(void)viewDidLoad{
UIColor *background = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"MainScreen.png"]];
selectionScreen.backgroundColor = background;
[background release]
}
You mentioned in comment above that your .png is under 300k. That's perhaps a touch big, but you're actually not looking at the right thing. A png gets expanded to a native CGImage object. I usually figure a 32-bit image with alpha takes up width * height * 4 bytes of memory. That's pretty much guaranteed to be bigger than the PNG it gets expanded from, and in your case could be quite big indeed. Enough so that the docs recommend not instantiating UIImages bigger than 1024 x 1024.
Now, one solution could be that -initWithPatternImage can take a small piece of your background, and will tile it when it's drawn. So your first shot at solving this would be to provide that method as small an image as possible, and let it tile to bigger sizes.
Second thing, the retention. You're correctly releasing your UIColor object after setting it on the background. You WANT that object you set it on to retain it! In a world of infinite memory, you'd want that button to retain its background color until the viewcontroller it's on gets dealloc'ed. If it's still huge and you really have to get rid of it before backing out of the view controller (say when you push to a new UINavigationController view or something), you could try setting background to nil (or a system default color maybe) in -viewDidDisappear and re-building your background in -viewWillAppear.
Wheb viewWillDisappear, you can set backgroundColor as another color, and release the background color you made.
-(void)viewWillDisappear:(BOOL)animated
{
// release original backgroundColor
// default backgroundColor is nil by UIView class reference.
selectionScreen.backgroundColor = nil;
}
Hope this can help you.
Did you try using something like:
button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:/frameOfChoice/];
[button setBackgroundImage:[UIImage imageNamed:#"MainScreen.png"] forControlState:UIControlStateNormal];
I'm not sure how this effects the memory usage tho.