Adding button gradient before appearing in iOS - ios

I want to use gradient for a button in iOS, but since the button's frame (button.layer.bounds) changes because of Auto Layout, I found that I have to put the insertSublayer in the viewDidAppear method -- which means the button first appears without the gradient and then gets repainted with it. Is there anyway to get the final button size in viewWillAppear so that I can apply the correct size gradient before it appears?
Here's how I do it now:
- (void)viewDidAppear:(BOOL)animated{
CAGradientLayer *gradient1=[CAGradientLayer layer];
gradient1.colors=[NSArray arrayWithObjects:(id)light.CGColor,(id)dark.CGColor,nil];
gradient1.cornerRadius=10;
gradient1.frame=_go_button.layer.bounds;
gradient1.borderColor=dark.CGColor;
gradient1.borderWidth=1;
[_go_button.layer insertSublayer:gradient1 atIndex:0];

Sometimes by asking a question leads you to finding your own answer.... Here's a link to a website I found that answered it: has the solution
The simple answer is to put the gradient code into viewDidLayoutSubviews instead of viewDidAppear.

Related

UIView content mode acts differently when override drawRect:

Im learning iOS. I've been reading Apple's View programming guide.
I did the followings to try out content mode:
I dragged a uiview into storyboard and made it my CustomView class.
Then i changed the content mode to be left and set the background color to be pink color.
Then there's a button that just simply changes the custom view's width and height to be 1.5 times bigger.
Now, i found an interesting thing:
I run this, and click the button, then:
Case 1: If i override the draw rect method
drawRect: overrided
Then the appearance of the view shifted down
Case 2: Without overriding the draw rect method
drawRect: not overrided
The size actually increased
After doing some search online and look into Apple's document, i couldnt any relavent things except one question mention that this might have something to do with drawLayer:inContext: behave differently if override the drawRect:
Does anyone know what is going on here?
(sorry about the formatting, this is a new account and i can't post more than 2 links.)
CODE:
For the CustomView, just either override drawRect or without it.
#import "CustomView.h"
#implementation CustomView
- (void)drawRect:(CGRect)rect{
//Do nothing, for case 2 i just commented out this method.
}
#end
For Changing the frame of customView:
- (IBAction)changeBound:(id)sender {
self.customView.frame = CGRectMake(self.customView.frame.origin.x, self.customView.frame.origin.y, self.customView.frame.size.width * 1.5, self.customView.frame.size.height * 1.5);
}
After doing some research, i think i figure out what happened:
So drawing background code is actually handled separately in -(void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context. That's why with empty drawRect, it still draws the background. Also, depending on the existence of drawRector not(Probably by calling respondsToSelector?), UIView behave different in drawLayer :inContext.
See Dennis Fan's answer in this link

UISlider change width of lines drawn on a view?

I am currently working on a drawing application in swift. So far I have implemented buttons that will change the colour of the drawings. I now have a UISlider and want to change the width of the drawings being made. Does anyone know
how this could be implemented, as in what code can I use for the IBAction function in the view controller?
You can use Value changed event.
Inside value changed event you can get the slider.value assign this value to the width factor.
-(IBAction)SliderValueChanged:(id)sender
{
UISlider * slider = (UISlider*)sender;
self.drawingWidth = slider.value;
//redraw with the new value
}
I think you have overrided touchesBegan drawLineFrom touchesMoved methods of the drawing view.
I came accross a well explained example for you. It explains how to control coloring, opacity and brush sizes as well.
Have a lok at this example

Swift: Change label text value as animation plays

I've followed this answer to create an animated circle, and it works just fine. In addition to the path, I draw a text in the center of the view with drawInRect. I would like that text to change during the animation, to reflect the percentage of the path that is visible at each moment. How can I achieve that?
Thanks.
The most promising post would likely be this one. It describes creating a new CALayer that keeps track of the progress, which can then fire a call back.
Otherwise you'll likely need to wangle something together by observing your view's presentationLayer.

iOS UIView derived view instance drawRect being called but not updating on screen?

Was hoping someone could help with this please? I've scanned through the forum and apple docs and can't find anything that matches my problem exactly.
I'm trying to animate a custom 'Composite' UIView derived class (with overidden drawRect) by changing a custom colour property (not one of the standard view properties like centre, alpha, backgroundColour etc), calling setNeedsDisplay and redrawing the view using drawRect over X seconds duration to produce a slow colour change from say, red to blue.
At the moment, all Composite::drawRect does internally is clear the context (the view has a default background colour set to clear) and fill the view using the colour provided. This works fine the first time it's called - the view appears on screen in the correct red colour.
My problem is that when I try to animate the view by updating the colour property, even though drawRect is being called everytime I call setNeedsDisplay and the colour being fed into the view instance is correct the view doesn't update on screen until I stop calling setNeedsDisplay (or rather, stop updating the custom view colour property). It's like every call to setNeedsDisplay pushes the view to the back of a list so it doesn't get updated on screen until it stops getting called (even though drawRect is being called).
For example - trying to change the colour from red to blue over 10 seconds, the view stays red for 10 seconds, then turns to blue in a single frame at the end of the property changing (and presumably when I stop calling setNeedsDisplay) rather than a slow fade between the two over the time duration.
Any ideas what's going on? I'm guessing I need to animate this using apple's own animation property stuff but I'd really prefer not to - I'm trying to make this cross platform if possible and I don't see why my own method shouldn't work.
The basics:
In case it matters, my composite view instance is a subview of an UIImageView. (I know imageview drawRect doesn't get called but I can't imagine this is a problem for it's subviews - after all, my Composite::drawRect is definitely being called).
I'm setting the right colour on my view instance - I've debug printed this to be sure - so the colour provided to the view goes from red to blue over however many seconds / frames.
I'm setting setNeedsDispay and drawRect is being called every time - again, debug printing confirms this.
This is happening over multiple frames and the app goes through the drawing update at the end of every frame - I.e I'm not blocking the render thread or anything - the app runs fine, it just doesn't update the view on screen even though its drawRect is being called, until I stop manipulating the property. Someone mentioned a similar problem where they were blocking the render thread in a single frame but I'm definitely not doing anything like that.
I've tried messing around with the following but they all produced the same results (i.e. view changed from red to blue in a single frame rather than a slow change over).
Updating the colour every frame but only calling setNeedsDisplay on my view every Xth frame (5, 10, 20, 30 etc)
Updating the colour every frame but not calling setNeedsDisplay unless the corresponding drawRect call from the last setNeedsDisplay has happened (i.e. set a flag to false in SetColour func, set same flag to true in drawRect, test against it when decided to call setNeedsDisplay) - same results.
setting the view bounds with ContentMode set to redraw to force an update - same results
tried calling setNeedsDisplay on the parent image view too - no change.
I'm guessing that this just isn't possible - can anyone explain why its not updating the v view onscreen even though drawRect is being called? Any ideas how I should do this? I don't think I would be able to do what I want to do if I tried animated one of the default view properties using apple's internal animation system but if I've got to use that....
Thanks!
:-)

Why setClipsToBounds:NO disables setCornerRadius: for UItableview?

I'm creating UIItableview. For the first cell I want to have a user Image with a button to allow him to change the image. (not so complicated).
Somehow I have a strange problem: When I set setMasksToBounds:NO the [self.userTable.layer setCornerRadius:20.0]; is simply get disabled.
I am attaching a code with output example:
//Initiate UserTable
//[self.userTable setClipsToBounds:NO];//from the documentation this line is set by default
[self.userTable.layer setCornerRadius:20.0];
[self.view addSubview:self.userTable];
later in cellForRowAtIndexPath: I add:
[myCellView.contentView addSubview:photo]; //My photo is UImageview
If I uncomment the line [self.userTable setClipsToBounds:NO] I get:
but my corners are not rounded any more......
I read the following questions
this and this and still cant figure that out?
Did someone had this problem and can provide a fix which will not force me to change all my code? and also how the 2 options are related to each other?
Thanks a lot.
Calling setCornerRadius applies a mask to your CALayer, which is then used to mask the bounds and create the rounded corner effect.
By calling setMasksToBounds:NO, you are disabling the mechanism used to round the corners.
In short, you can't have it both ways.
Consider making that row in the tableview taller, or using a custom view instead of a standard UITableViewCell.

Resources