I want to have a UIView subclass that has a border image, but I don't want or care about this 'new' frame/bounds around the border image itself.
What I wanted to do was just use drawRect and draw outside of the rect but all drawing is clipped and I don't see a way to not clip drawing outside of this context rect.
So now I have added a sublayer to the views layer, set [self clipsToBounds] on the view and override setFrame to control my sublayers frame and always keep it at the proper size (spilling over the views frame by 40px).
The problem with this is that setFrame on a uiview by default has no animation but seTFrame on a calayer does.
I cant just disable the animations on the calayers setFrame because if I were to call setFrame on the uiview inside a uiview animation block the calayer would still have its animation disabled.
The obvious solution is to look up the current animationDuration on the uiview animation and set a matching animation on the sublayer, but I don't know if this value is available. And even if it is, I'm afraid that calling an animation from within another animation is wrong.
Unfortunately the best solution is to not use a calayer at all and just add a uiview as a subview and draw into that just like I am drawing into my layer, and hope that with autoresizingMask set to height and width that everything will 'just work'. Just seems like unnecessary overhead for such a simple task.
My solution would be to override the initWithFrame: to add the surrounding border pixels and contain the content in a subview. It probably is unneccesary overhead but definietly the "cocoa" route. It's probably going to be easier in the end too since a subview structure will allow you to edit the content seperatly from the border so you dont have to redraw the border when you redraw the content. And keeping them seperate simply makes sense from a OOP perspective.
The clipsToBounds route is probably the easiest route besides the subview structure but managing the border and content in one drawing cycle and in one object will probably be a lot more work so it'll be worth the overhead.
Excuse any typos, typed this from my iPhone.
Related
I've got a UIView with a UILabel on top. I have the UILabel's content mode set to 'UIContentModeLeft'. As expected, when I animate the frame of the UIView to be smaller than the original size, the label 'jumps' to the final frame without animating nicely.
As far as I can see, UIContentModeRedraw does not force 'drawRect' to be called on every 'animated frame'. I've tried using a custom CALayer as well but can't seem to cause the frame to resize smoothly.
Is there any way to do this? The animation as it stands is extremely glitchy. UIContentModes are not useful and I can't use a frame for contentStretch as well as none of the edges of the label can be stretched. What I really need is a 'refresh' of the label every time the parent view resizes.
There's no way of doing this unfortunately, so I've learnt. The only other way is to actually run a timer that updates the frame every time it's invoked. This results in a very jerky animation given a resize of a complex view is time consuming. I ended up achieving the same thing with some pre-rendered onscreen elements and a whole lotta 'magical effects' behind the scene.
I have a CustomView, inside which I have added my custom CALayer ([self.layer addSublayer:...]) which I subclassed to do some custom drawing in drawInContext method of my layer. I draw there simple paths.
The CustomView is added as subview to UIScrollView.
The problem is when I zoom, the content doesn't get redrawn so the path looks blurry.
How to fix that? I tired to call setNeedsDisplay on the layer and sublayer when zoom ends, but without results.
Example of blurry path and correct one after zooming:
I've got a UIScrollView whose zoom behavior I want to confine to the horizontal axis. I've accomplished that through using a custom UIView as the viewForZoomingInScrollView: and overriding setTransform:. So far so good – the view only zooms horizontally.
One catch: The container view includes some stretchable UIImage instances in UIImageViews. Obviously, with the transform in effect, the images distort.
What's the best bet for either redrawing the view so that the images aren't distorted, or, zooming the view in such a way as to not require transforms in the first place?
Thanks for any help you can offer.
You sure way of achieving this is to make your UIImageView into a custom UIView, and have its drawRect: code do the right thing: draw both stretched and unstretched elements.
I have a UIScrollView with a custom content view that uses drawRect to display its contents.
In my drawRect method I respect the passed CGRect parameter and only draw what's needed.
However, each time the drawRect is called it is passed the entire bounds of the view, even if it is several thousand pixels, and I'm worried about performance and memory use. Is there any way to make a UIScrollView limit this, or am I worrying too much over nothing?
Also, I've tried using CATiledLayer as the layer, and while this corrects the passed rect, it feels like I'm misusing the class. Also, the view still keeps all the pixels backed as far as I can tell. (Even if it doesn't draw some of them right away)
using CATiledLayer is probably the best option. I'm familiar with CATiledLayer as a concept, but never used it myself, so I'm not going to say anything about that. What I can say, is that if you subclass the UIScrollView and implement
layoutSubviews
you should be able to redraw the subviews toll-free with good performance, as long as you implement a construction using
CGRectIntersectsRect()
In which you can see if the current visible rect, in the case of a subclass
[self bounds]
intersects with the rect of the object you want to draw. if it doesn't, you can choose to ignore the object or even (if it is already on the scrollview) remove it from superview. if it does, you can place the object on superview.
again, CATiledLayer is a way better solution, but if you feel like you are misusing it, try the approach I described.
1.content view large than scrollview is true..
2.may be you should realize UiScrollViewDelegate's
scrollViewDidScroll
caculate content view 's rect that should be redrawed ,not the entire bounds .
I'm using the method described at How do I draw a shadow under a UIView? to draw shadow behind a view's content. The shadow is clipped to the view's bounds, although I disabled "Clip Subviews" in Interface Builder for the view. Is it possible to draw a shadow around a view and not only in a view?
I don't want to draw the shadow inside the view because the view would receive touch events for the shadow area, which really belongs to the background.
Instead of manual drawing in drawRect, consider setting properties on the the UIView's Core Animation layer for drawing a shadow.
For example:
[descriptionInput setClipsToBounds:NO];
[descriptionInput.layer setShadowColor:[[UIColor blackColor] CGColor]];
[descriptionInput.layer setShadowOpacity:0.8];
[descriptionInput.layer setShadowOffset:CGSizeMake(0.0, 3.0)];
For this to work, you need to include QuartzCore:
#import <QuartzCore/QuartzCore.h>
clipsToBounds only controls the clipping for children of a view, not drawing of that view itself; hence it's not solving your problem.
If you can draw your shadow onto a different view and add that as a child, it won't get clipped. However, I don't know how possible that is with the method you're using :(
It is not encouraged to draw outside view bounds. Maybe you can include the shadow directly in your background...
Regards,