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
Related
I have a View Controller that creates its view programatically through the loadView method. The purpose of the view is to display a data models contents. When the view loads it is aligned correctly under the status and navigation bar.
But at a later point I present another view modally to allow the user to select a different data model to populate the view. This causes the the loadView to get called again and re-create the required UI for the new data model. The problem is that the view's contents now appear under the status and navigation bars!
Please note that I am not using auto-layout due to having to support iOS4 :( Also if I include the extendedLayout fix - it does fix the problem but only after the modal's dismiss animation completes leaving a jump down effect. My code below, thanks for any help.
- (void)loadView {
CGRect frame = CGRectMake(0, 0, [Constants ScreenWidth], [Constants ScreenHeight] - StatusBarHeight - ToolbarHeight);
self.view = [[UIView alloc] initWithFrame:frame];
self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight;
self.view.autoresizesSubviews = YES;
self.view.backgroundColor = [Constants categoriesScreenBackgroundColor];
CGRect scrollFrame = CGRectMake(0, 0, [Constants ScreenWidth], [Constants ScreenHeight] - StatusBarHeight - ToolbarHeight - ToolbarHeight);
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:scrollFrame];
scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight |
UIViewAutoresizingFlexibleBottomMargin |
UIViewAutoresizingFlexibleTopMargin;
[self.view addSubview:scrollView];
_toolbarViewController = [self createToolbarViewController];
[self.view addSubview:_toolbarViewController.view];
_toolbarViewController.productInfoWorkflowState = _productInfoWorkflowState;
UIView *containerView = [[UIView alloc] initWithFrame:scrollView.frame];
containerView.backgroundColor = [UIColor clearColor];
_headerViewController = [self createHeaderViewController];
[containerView addSubview:_headerViewController.view];
_menuViewController = [[ProductInfoMenuViewController alloc] initWithBatch:[self batchData]];
_menuViewController.delegate = self;
[containerView addSubview:_menuViewController.view];
CGRect categoriesFrame = _menuViewController.view.frame;
categoriesFrame.origin.y = _headerViewController.view.frame.size.height;
_menuViewController.view.frame = categoriesFrame;
CGRect viewFrame = containerView.frame;
viewFrame.size.height = _headerViewController.view.frame.size.height + _menuViewController.view.frame.size.height;
containerView.frame = viewFrame;
[scrollView addSubview:containerView];
scrollView.contentSize = containerView.frame.size;
_starViewController = [[StarViewController alloc] initForProduct:_productData With:[StarredItems new]];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:_starViewController.view];
}
Screen layout after first load:
Screen layout after second load:
With Leo's suggested fix, the scrollView is correct BUT the toolbar at the bottom now appears incorrectly. Code I used (placed after the toolbar creation code above):
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0")) {
self.automaticallyAdjustsScrollViewInsets = NO;
scrollView.scrollIndicatorInsets = UIEdgeInsetsMake(64.0f, 0.0f, 0.0f, 0.0f);
scrollView.contentInset = UIEdgeInsetsMake(64.0f, 0.0f, 0.0f, 0.0f);
}
Results:
Add following code its work for me for same issue, may be its help you
/* ios 7 Change */
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7)
{
self.edgesForExtendedLayout = UIRectEdgeNone;
self.automaticallyAdjustsScrollViewInsets = NO;
}
Does this only happen on iOS 7?
Give this a try:
self.navigationController.navigationBar.translucent = NO;
Try following:
Toolbar.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
try this
CGRect frame = CGRectMake(0, StatusBarHeight, [Constants ScreenWidth], [Constants ScreenHeight] - StatusBarHeight - ToolbarHeight);
self.view = [[UIView alloc] initWithFrame:frame];
self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight;
self.view.autoresizesSubviews = YES;
self.view.backgroundColor = [Constants categoriesScreenBackgroundColor];
CGRect scrollFrame = CGRectMake(0, StatusBarHeight, [Constants ScreenWidth], [Constants ScreenHeight] - StatusBarHeight - ToolbarHeight - ToolbarHeight);
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:scrollFrame];
scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight |
UIViewAutoresizingFlexibleBottomMargin |
UIViewAutoresizingFlexibleTopMargin;
[self.view addSubview:scrollView];
I think the problem is due to incorrect automatic set of content insets of the scrollview.
Try the following. In your loadView, set self.automaticallyAdjustsScrollViewInsets to NO (only if NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1). Now, set the contentInset and scrollIndicatorInsets to the correct values depending on OS version:
scrollview.contentInset = scrollview.scrollIndicatorInsets = UIEdgeInsetMake(NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_6_1 ? 0 : 64, 0, 0, 0);
My problem was solved unmarking the check "Adjust Scroll View Insets" in the View Controller (using Storyboards).
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);
I created my own subclass of UINavigationBar in order to enable custom background that is taller than 44pxs.
I did it by overriding these two methods:
-(void) drawRect:(CGRect)rect
{
[self.backgroundImage drawInRect:CGRectMake(0, 0, self.backgroundImage.size.width, self.backgroundImage.size.height)];
}
- (CGSize)sizeThatFits:(CGSize)size
{
CGRect frame = [UIScreen mainScreen].applicationFrame;
CGSize newSize = CGSizeMake(frame.size.width , self.backgroundImage.size.height);
return newSize;
}
And this is the result:
Now, my problem as you can see is that all the UIBarButtonItem's (and the titleView) are placed at the bottom of the navigation bar.
I would like them to be pinned to the top of the bar (with some padding of course).
What to I need to override to achieve that?
Thanks!
EDIT:
This is the solution that I used:
-(void) layoutSubviews
{
[super layoutSubviews];
for (UIView *view in self.subviews)
{
CGRect frame = view.frame;
frame.origin.y = 5;
view.frame = frame;
}
}
Does the trick for idle state, still have some weird behavior on push and pop items.
Try to override layoutSubviews: call [super layoutSubviews] inside and then reposition the items.
To solve the push/pop issue use setTitleVerticalPositionAdjustment in sizeThatFits:(CGSize)size
- (CGSize)sizeThatFits:(CGSize)size {
UIImage *img = [UIImage imageNamed:#"navigation_background.png"];
[self setTitleVerticalPositionAdjustment:-7 forBarMetrics:UIBarMetricsDefault];
CGRect frame = [UIScreen mainScreen].applicationFrame;
CGSize newSize = CGSizeMake(frame.size.width , img.size.height);
return newSize;
}
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];
//...
}
I'm trying to put a UITextView inside a custom subclass of UIAlertView that I create using a background image of mine. The UITextView is only for displaying large quantities of text (so the scrolling).
Here is the code of my subclass
- (id)initNarrationViewWithImage:(UIImage *)image text:(NSString *)text{
if (self = [super init]) {
self.backgroundImage = image;
UITextView * textView = [[UITextView alloc] initWithFrame:CGRectZero];
self.textualNarrationView = textView;
[textView release];
self.textualNarrationView.text = text;
self.textualNarrationView.backgroundColor = [UIColor colorWithRed:0.0 green:1.0 blue:0.0 alpha:1.0];
self.textualNarrationView.opaque = YES;
[self addSubview:textualNarrationView];
}
return self;
}
- (void)drawRect:(CGRect)rect {
NSLog(#"DRAU");
CGSize imageSize = self.backgroundImage.size;
[self.backgroundImage drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];
}
- (void)layoutSubviews {
CGSize imageSize = self.backgroundImage.size;
self.textualNarrationView.bounds = CGRectMake(0, 0, imageSize.width - 20, imageSize.height - 20);
self.textualNarrationView.center = CGPointMake(320/2, 480/2);
}
- (void)show{
[super show];
NSLog(#"SCIO");
CGSize imageSize = self.backgroundImage.size;
self.bounds = CGRectMake(0, 0, imageSize.width, imageSize.height);
self.center = CGPointMake(320/2, 480/2);
}
This is my first time subclassing a UIView, I'm surely missing something since the background image appears correctly, the UITextview also but after a fraction of a second it jumps all up (seems like a coordinate problem).
I've finally created my own customized version of UIAlertView and provided a UITextView inside of it. Here is what brought me to do so.
By doing it I experienced a weird behaviour when I was trying to attach the UITextView to a background UIImageView as a subview, it wasn't responsive to touches anymore, the way to make it work as expected was to attach it to the base view and implement the following method
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
by making it return YES when encessary.