UIScrollview isn't displayed - iphone

Hi I'm testing out drawing and created a simple scrollview and embedded a subview without using interface builder. It displays correctly when I position everything at the origin but if I move everything down past y = 40 it disappears. Alternatively, the scrollview and subview independently display fine at whatever position I place them ie. without setting the view as a subview. Can anyone explain why this would happen?
thanks
the view to be embedded:
#implementation BLRView
- (id) initWithFrame:(CGRect) frame
{
self = [super initWithFrame:frame];
if(self)
{
[self setBackgroundColor:[UIColor blackColor]];
}
return self;
}
- (void) drawRect:(CGRect)dirtyRect
{
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGRect bounds = [self bounds];
CGContextSetLineWidth(ctx, 30);
CGContextSetStrokeColorWithColor(ctx, [UIColor redColor].CGColor);
float dashphase = 1.0;
float dashlengths[] = {1.0, 20.0};
CGContextSetLineDash(ctx, dashphase , dashlengths, 2);
CGContextMoveToPoint(ctx, bounds.origin.x, bounds.origin.y);
CGContextAddLineToPoint(ctx, bounds.size.width , bounds.origin.y);
CGContextStrokePath(ctx);
}
#end
and in the appdelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
CGRect screenRect = [[self window] bounds];
//this displays
CGRect viewFrame = CGRectMake(0, 0, screenRect.size.width * 3, 50);
CGRect scrollFrame = CGRectMake(0, 0, screenRect.size.width, 50);
//this is slightly cut off at the bottom
//CGRect viewFrame = CGRectMake(0, 30, screenRect.size.width * 3, 50);
//CGRect scrollFrame = CGRectMake(0, 30, screenRect.size.width, 50);
//this isnt shown
//CGRect viewFrame = CGRectMake(0, 100, screenRect.size.width * 3, 50);
//CGRect scrollFrame = CGRectMake(0, 100, screenRect.size.width, 50);
UIScrollView *scrollview = [[UIScrollView alloc] initWithFrame:scrollFrame];
BLRView *view = [[BLRView alloc]initWithFrame:viewFrame];
[[self window] addSubview:scrollview];
[scrollview addSubview:view];
[scrollview setContentSize:viewFrame.size];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}

Sorry, i'm an idiot. The embedded view frame is being pushed down from the origin of the scroll frame
these should be
CGRect viewFrame = CGRectMake(0, 0, screenRect.size.width * 3, 50);
CGRect scrollFrame = CGRectMake(0, 30, screenRect.size.width, 50);

Related

status message corrupts main window in my iPhone app

In my iOS app when a button is pressed an event is initiated and at the bottom of the screen appears a status message informing the user about a successful or failed operation.
The status message appear and disappear with the following code.
this one show the message
- (void) showMessage:(NSString*)text
{
CGRect frame = [[self view] frame];
if(statusView == nil)
{
messageViewWindow = [[UIWindow alloc] initWithFrame:CGRectMake(0, frame.size.height-29,
frame.size.width, 0)];
statusView = [[StatusMessageView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, 0)
Text:text
andShowIndicator:NO];
[messageViewWindow addSubview:statusView];
[messageViewWindow makeKeyAndVisible];
}
UILabel *label = [statusView getTextLabel];
UIImageView *imageView = [statusView getBackImageView];
CGSize stringSize = [text sizeWithFont:[Constants getLabelFont]];
int xCoordinate = (messageViewWindow.frame.size.width - stringSize.width)/2;
[UIView beginAnimations:nil context:nil];
messageViewWindow.frame = CGRectMake(0, frame.size.height-59, frame.size.width, 30);
statusView.frame = CGRectMake(0, 0, frame.size.width, 30);
label.frame = CGRectMake(xCoordinate,5,stringSize.width,20);
imageView.frame = CGRectMake(0, 0, frame.size.width, 30);
[UIView commitAnimations];
[NSTimer scheduledTimerWithTimeInterval:2.0f target:self selector:#selector(hideMessage) userInfo:nil repeats:NO];
}
and this one hides the message
- (void) hideMessage
{
UILabel *label = [statusView getTextLabel];
UIImageView *imageView = [statusView getBackImageView];
CGRect labelFrame = label.frame;
[UIView beginAnimations:nil context:nil];
messageViewWindow.frame = CGRectMake(0, [UIScreen mainScreen].applicationFrame.size.height-29, [UIScreen mainScreen].applicationFrame.size.width, 0);
statusView.frame = CGRectMake(0, 0, [UIScreen mainScreen].applicationFrame.size.width, 0);
label.frame = CGRectMake(labelFrame.origin.x, 0, labelFrame.origin.y, 0);
imageView.frame = CGRectMake(0, 0, [UIScreen mainScreen].applicationFrame.size.width, 0);
[UIView commitAnimations];
}
strange thing is that the message is shown and after two seconds dissapears, however the main window lost functionality, like the copy and paste ability.
Do you see something wrong in my methods? Is there any certain way, calling the "animations" code?
Since you are writing [messageViewWindow makeKeyAndVisible];, you have to write [self.view.window makeKeyAndVisible] in hideMessage to let the self.view.window handle all the userinteraction again.
This is because you use a UIWindow to display your view, which is not a good idea (it is not recommended to create UIWindows by yourself, as explained in the "Overview" paragraph of the documentation.
Moreover, you make your window the keywindow but don't restore the standard window at the end when you hide it, thus your problems with the events later.
And last, you use obsolete APIs for the animations, which is deprecated since iOS4 is out (and I guess you don't code for iOS3 or earlier), you should really use the new APIs that have been introducted 3 iOS versions ago now. Besides, it will avoid the overhead to create an NSTimer for that.
So you code can become:
- (void) showMessage:(NSString*)text
{
CGSize sz = self.view.window.frame.size;
CGRect hiddenFrame = CGRectMake(0, sz.height-29, sz.width, 0);
if(statusView == nil)
{
statusView = [[StatusMessageView alloc] initWithFrame:hiddenFrame
text:text
andShowIndicator:NO];
[self.window addSubview:statusView];
}
UILabel *label = [statusView getTextLabel];
UIImageView *imageView = [statusView getBackImageView];
CGSize stringSize = [text sizeWithFont:[Constants getLabelFont]];
int xCoordinate = (sz.width - stringSize.width)/2;
label.frame = CGRectMake(xCoordinate,5,stringSize.width,20);
imageView.frame = CGRectMake(0, 0, frame.size.width, 30);
[UIView animateWithDuration:1.f animations:^{
statusView.frame = CGRectMake(0, sz.height-59, frame.size.width, 30);
} completion:^{
// When show animation is done, schedule the start of the hide animation with a delay of 2 seconds
[UIView animateWithDuration:1.f delay:2.f options:0 animation:^{
statusView.frame = hiddenFrame;
} completion:nil];
}];
}

Subclassing UIScrollview

I have been trying desperately to draw some images into a view. The view should be inside a scrollview. For that I subclassed UIScrollview and override the drawRect method in it. And added this as my UIView's subview.
#interface DrawAnotherViewClass : UIScrollView<UIScrollViewDelegate> {
}
#end
#implementation DrawAnotherViewClass
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
CGRect fullScreenRect=[[UIScreen mainScreen] applicationFrame];
self.frame = fullScreenRect;
self.contentSize = CGSizeMake(600, 600);
self.showsHorizontalScrollIndicator = YES;
self.showsVerticalScrollIndicator = NO;
self.pagingEnabled = YES;
}
return self;
}
- (void)drawRect:(CGRect)rect
{
// Drawing code
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGContextMoveToPoint(context, 10.0f, 50.0f);
CGContextAddLineToPoint(context, 10.0f, 200.0f);
CGContextStrokePath(context);
CGContextMoveToPoint(context, 8.0f, 77.0f);
CGContextAddLineToPoint(context, 300.0f, 77.0f);
CGContextStrokePath(context);
CGContextSetRGBFillColor(context, 0, 0, 255, 0.1);
CGContextSetRGBStrokeColor(context, 0, 0, 255, 1);
CGContextStrokeEllipseInRect(context, CGRectMake(65.0, 33.5, 25, 25));
UIImage *image1 = [UIImage imageNamed:#"PinDown1.png"];
UIImage *image2 = [UIImage imageNamed:#"pinGreen_v1.png"];
CGPoint drawPoint = CGPointMake(0.0f, 10.0f);
[image2 drawAtPoint:drawPoint];
for(int i =1; i<20; i++){
CGPoint drawPointOne = CGPointMake(40.0f * i, 40.0f);
[image1 drawAtPoint:drawPointOne];
}
}
Am I missing something here. Is this the right way to go.
If the view that should perform the drawing resides in that UIScrollView, you have to put the - (void)drawRect:(CGRect)rect method into that view's class method and not into the UIScrollView subclass.

CGContextDrawPDFPage is drawing the page on the wrong origin point

Edit: It seems that the origin point's components are been multiplied by 2 when drawing the PDF page. Is something I'm doing causing this?
I have a UIViewController that displays a PDF page on a UIScrollView. the PDF page itself is drawn on a CATiledLayer, however, when my view controller draws the layer there is a considerable offset between the layer's bounds and the drawn PDF. As you can see in the picture, the page should have been drawn on the yellow view:
Here is the relevant code that draws the page:
- (void)refreshPage
{
if(contentView) {
for(UIView *v in self.view.subviews) {
[v removeFromSuperview];
[v release];
}
}
CGRect pageRect = CGRectIntegral(CGPDFPageGetBoxRect(self._document.page, kCGPDFCropBox));
pageRect.origin.x = ((self.view.frame.size.width / 2) - (pageRect.size.width / 2));
CATiledLayer *tiledLayer = [CATiledLayer layer];
tiledLayer.delegate = self;
tiledLayer.tileSize = CGSizeMake(1024.0, 1024.0);
tiledLayer.levelsOfDetail = 1000;
tiledLayer.levelsOfDetailBias = 1000;
tiledLayer.frame = pageRect;
contentView = [[UIView alloc] initWithFrame:pageRect];
[contentView.layer addSublayer:tiledLayer];
CGRect viewFrame = self.view.frame;
viewFrame.origin = CGPointZero;
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:viewFrame];
//[scrollView setBackgroundColor:[UIColor cyanColor]];
//[contentView setBackgroundColor:[UIColor yellowColor]];
scrollView.delegate = self;
scrollView.contentSize = pageRect.size;
scrollView.maximumZoomScale = 1000;
[scrollView addSubview:contentView];
[self.view addSubview:scrollView];
pagingViewController = [[PDFPagingViewController alloc] initWithDocument:self._document AndObserver:self];
[self.view addSubview:pagingViewController.view];
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return contentView;
}
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
{
if(self._document) {
[layer setBackgroundColor:(CGColorRef)[UIColor redColor]];
CGRect drawingRect = CGContextGetClipBoundingBox(ctx);
CGContextSetRGBFillColor(ctx, 1.0, 1.0, 1.0, 1.0);
CGContextFillRect(ctx, drawingRect);
CGContextTranslateCTM(ctx, 0.0, layer.bounds.size.height);
CGContextScaleCTM(ctx, 1.0, -1.0);
CGContextConcatCTM(ctx, CGPDFPageGetDrawingTransform(self._document.page, kCGPDFCropBox, layer.bounds, 0, true));
CGContextDrawPDFPage(ctx, self._document.page);
}
}
You need to change when you set the pageRect's origin (which I assume you do to center in the view). You are setting both the layer's frame and the contentView's frame to the offset pageRect when you really intend to offset only one.
-(void)refreshPage {
//...
CGRect pageRect = CGRectIntegral(CGPDFPageGetBoxRect(self._document.page, kCGPDFCropBox));
CATiledLayer *tiledLayer = [CATiledLayer layer];
//...
tiledLayer.frame = pageRect;
// set the pageRect origin now to center the contentView, not the layer
pageRect.origin.x = ((self.view.frame.size.width / 2) - (pageRect.size.width / 2));
contentView = [[UIView alloc] initWithFrame:pageRect];
[contentView.layer addSublayer:tiledLayer];
//...
}

iphone landscape mode problem again

I have tested everything but I cant get it to work.
This is how I set up my program:
CGRect contentRect = CGRectMake(0, 0, 480, 320);
CGRect screenBounds = [[UIScreen mainScreen] bounds];
_window = [[UIWindow alloc] initWithFrame: contentRect];
_view = [[GLView alloc] initWithFrame: screenBounds];
CGAffineTransform transform = CGAffineTransformMakeRotation(3.14159/2);
_view.transform = transform;
_window.frame = contentRect;
_window.bounds = contentRect;
_window.window.bounds = contentRect;
_window.frame = contentRect;
_view.window.bounds = contentRect;
_view.bounds = contentRect;
_view.bounds = contentRect;
_view.frame = contentRect;
[_window addSubview: _view];
[_window makeKeyAndVisible];
I set up my opengl like this:
glViewport(0, 0, 480, 320);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof( 0, 480, 0, 320, -1, 1 );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
and as you can see one third from the right is black? what am i missing?
You should set rotation in your model/view matrix and not in the view.

UIPicker first appears black

I have the following code to draw a custom picker. Unfortunately when the view is first drawn is black. Only when I touch it does it appear.
How can I fix this?
Here is the relevant code in the UIView:
- (void)drawRect:(CGRect)rect
{
[self createPicker];
[self addSubview:dPicker];
//[dPicker reloadComponent:1];
}
-(void) createPicker
{
dPicker = [[UIPickerView alloc] initWithFrame:CGRectZero];
CGSize pickerSize = [dPicker sizeThatFits:CGSizeZero];
dPicker.frame = [self pickerFrameWithSize:pickerSize];
dPicker.delegate=self;
dPicker.showsSelectionIndicator = YES;
dPicker.hidden=NO;
}
- (CGRect)pickerFrameWithSize:(CGSize)size
{
CGRect screenRect = [[UIScreen mainScreen] applicationFrame];
CGRect pickerRect = CGRectMake( 0.0,
screenRect.size.height - 44.0 - size.height,
size.width,
size.height);
return pickerRect;
}
Fixed it. Called the subview from UIViewController instead of the the UIView