I have a UIScrollView that contains a UIView onto which I am drawing a rather complex graphic using CGPaths. After the view finishes loading the graphic is distorted in that it is elongated horizontally and vertically. If I redraw it, it looks normal.
Any ideas on what is causing this and how to fix it?
When you initialise your UIView, use initWithFrame and set the frame to the correct size that it will be after everything is drawn, etc. If you are not sure here are some ideas:
Get the 'bounds' of the parent view.
Call layoutSubviews on the root view, then get its frame, then create your UIView and add it to its parent.
Related
I'm trying to implement an owner-drawn view that is a subclass of UIScrollView. Basically, I want to custom-draw the contents of the view, and then have the stuff I've drawn be scrollable.
I've overridden drawRect in my view and I'm able to draw my contents, scaled to the size of the UIScrollView's contentSize property (so some of my custom drawing is not visible, as I intended).
The problem is that the content then never moves. I can drag my finger up and down, and this makes the UIScrollView's scrollbars appear, but my custom-drawn content never moves or changes - I still always only see the top half.
How can I custom-draw content for this UIScrollView so that what I've drawn is scrollable?
Are you calling [super drawRect]; at the end of your own drawRect method?
Edit
I misread the question. You'll need to create your own UIView subclass and put your overridden drawRect in that. Then, add that view as a child of the UIScrollView.
So I made a UIView subclass let's called it 'MyView' that simply draws a line inside the DrawRect method.
I then drag a UIImageView in interface builder and put it inside MyView. But now when I run the program it's obscuring the line that I'm drawing. I'm wondering, is there a way for me to draw the line on top of the image that I have dragged into my View?
No, you'll have to reorganise the view hierarchy. CoreGraphics uses a painters model so views behind will always be drawn over by views infront. To solve this you could use a container view that holds your image view and has a transparent view (line drawing view) that sits over the image view.
Another option is to draw the image using core graphics calls in your drawRect method and then draw the line over it.
One way is to have whatever adds MyView to add your UIImageView on top of MyView. It's not ideal (you probably have good reasons for keeping MyView and the UIImageView in a single class) but definitely solves your problem (I recently did this, only, I added it to the keyWindow =)
I would use a CAShapeLayer that has a path representing the line, and insert that layer ahead of the built-in view layer. Then it should draw on top.
I have a custom UIView that is composed entirely of CALayers.
In the awakeFromNib method it creates and sets all the CALayers into their appropriate positions (CAGradientLayer, several CATextLayers, and a few custom CALayer subclasses). The custom UIView does not override the drawRect: method because there's no drawing done directly into the view (all of the drawing is done in the sublayers).
So I took this view and embedded it in a UIScrollView. The problem? No scroll bars appear and the view does not scroll. The view is clearly larger than the bounds of the scroll view, and instead of allowing me to scroll, it just cuts off at the scroll view bounds.
What could be wrong here?
You have to set the scrollView's contentSize.
I created a UIView xib in Interface Builder and tried everything I could to indicate that the UIView should center itself, anchor itself at center, orient itself in central coordinates, etc. etc.
But whenever I add it as a subview in code, I also have to programmatically set its frame up with CGRectMake() or else it will always add to the top-left of its parent. The math to reframe it is pointless and ugly, so I presume I'm just not twiddling a bit in the IB inspector correctly.
Can anyone confirm this is possible, and if so, what I need to do in IB to accomplish this?
Why don't you just set .center of the subview just added, to be the point created by halving the width and height of the superview?
Either that or define the rectangle that view is going into with IB (I'm imagining a container view) and simply set the frame of the view you are adding to containerView.bounds (bounds is a position independent value and so x,y will be 0 while size will equal the container size.
Centering but maintaining size isn't possible in IB. Centering but maintaining margins to its superview is though.
You will have to override the layoutSubviews message or simply keep the calculation code you wrote.
My setup is a UIScrollView in the center of the screen (on the iPhone - like 300x400 positioned in the center) that contains a UIView of the same width, so it scrolls it vertically. In this UIView i draw custom subviews with labels etc (it's a scoreboard with various colors).
What i'd like to have is some shadow below my UIScrollView, so that the whole scrolling scoreboard floats over my background.
I have found this nice post
How do I draw a shadow under a UIView?
I use this code in my ScrollView subclass but it doesn't work for me. Maybe because I don't draw the actual shapes in the ScrollView's drawRect: (since they are drawn on the UIView).
Also I guess that in order to have the View scroll in the ScrollView and the shadow of the ScrollView outside the scrolling area, I guess I should extend the "bounds" of the ScrollView, right?
It's not quite clear to me what you're asking but, if you want the scrollView contents to scroll over a static image you simply need to add a UIView (or more likely a UIImageView) to your superview and then add your UIScrollView to that. If you set he background colour of the UIScrollView to be celarColor, the background image will show through - so you have a view heirarchy like:
UIWindow
UIView <----- your background here
UIScrollView
Scrolling subviews <----- high score table here
If you draw your highscore table in the scrolling subviews using CoreGraphics, the answer in the question you linked to will also work.
How about explicitly filling the entire self.bounds rectangle in your scroll view subclass' drawRect: method before calling super?
Another idea is to put the scroll view inside of another view which does the shadow drawing.