How to put a picture below navigationController? - objective-c

I want to build an iPhone app for my band.
I wondered how to put a picture below the navigationController, which is visible only on pulling down (let's have a glance to this app) :
http://img11.hostingpics.net/pics/227613image.jpg
Thank a lot.

use scrollview method
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGPoint offset = scrollView.contentOffset;
CGRect bounds = scrollView.bounds;
CGSize size = scrollView.contentSize;
UIEdgeInsets inset = scrollView.contentInset;
float y = offset.y + bounds.size.height - inset.bottom;
float h = size.height;
if(scrollView.contentOffset.y < 0.0f && scrollView.contentOffset.y > -80.0f)
{
//
display your image at this point
NSLog(#"\n pos: %f of %f", y, h);
}

You can do it much easier:
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0,0,320,1000)];
[self.view addSubview:scrollView];
This will add a scrollView :)
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,320,HEIGHTYOUWANT)];
imgView.image = [UIImage imageName:#"band.png"];
[scrollView addSubview:imgView];
This will add a picture of your Band, which has to be in your Projectfolder at the top of the scrollView, so if you scroll down, the picture goes with it :)
CREATE A UINAVIGATIONBAR HERE
[self.view addSubview:navigationBar];
//^ it has to be self.view not scrollView otherwise the navigationbar moves too

Related

UILabel inside UIView produces rounded corner with "square corner"

I have an UIView which I created and set background color to white. This view contains UILabel, which is a class called BubbleView. (Sorry I cannot add a picture because you need reputation 10+ :(
PROBLEM:
1. The following code produces a gray Label with rounded corner with gray-border square corner tips. This is because the UIView produces the square corner tips. The UILabel is rounded. Please note that I already set the background of UIView to white.
2. My text string of the UILabel is hiding behind UIView, so it is not displayed.
I'd love to show you pictures, but I am new and I cannot add pictures until I get to 10+ reputations.
http://i.stack.imgur.com/CdRjy.png
http://i.stack.imgur.com/zCdCV.png
Here is my code for setting the text and the view:
BubbleView:
- (void)drawRect:(CGRect)rect
{
const CGFloat boxWidth = self.bubbleWidth;
const CGFloat boxHeight = self.bubbleHeight;
NSLog(#"text, width, height: %#, %f, %f", self.text, self.bubbleWidth, self.bubbleHeight);
CGRect boxRect = CGRectMake(
roundf(self.bounds.size.width - boxWidth) / 2.0f,
roundf(self.bounds.size.height - boxHeight) / 2.0f,
boxWidth,
boxHeight);
UIBezierPath *roundedRect = [UIBezierPath bezierPathWithRoundedRect:boxRect cornerRadius:14.0f];
[[UIColor colorWithWhite:0.3f alpha:0.8f] setFill];
[roundedRect fill];
NSDictionary *attributes = #{
NSFontAttributeName : [UIFont systemFontOfSize:16.0f],
NSForegroundColorAttributeName : [UIColor whiteColor]
};
CGPoint textPoint = CGPointMake(
self.center.x+boxWidth/2,
self.center.y+boxHeight/2);
NSLog(#"text point origin: %f, %f", textPoint.x, textPoint.y);
[self.text drawAtPoint:textPoint withAttributes:attributes];
}
Main View Controller:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor whiteColor];
[self setText];
}
-(void) viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
[self setText];
}
- (void) setText
{
NSString *textR = #"I need this text to show up on autolayout so that i could continue working";
UIFont* font = [UIFont fontWithName:#"HelveticaNeue" size:14.0f];
CGSize constraint = CGSizeMake(250,9999);
CGRect textRect = [textR boundingRectWithSize:constraint
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName:font}
context:nil];
BubbleView *hostView = [[BubbleView alloc] initWithFrame:CGRectMake(20.0f, 160.0f, textRect.size.width+20, textRect.size.height+20)];
hostView.bubbleWidth = textRect.size.width+20;
hostView.bubbleHeight = textRect.size.height+20;
hostView.text = textR;
hostView.layer.cornerRadius = 10.0f;
self.view.layer.masksToBounds = TRUE;
[hostView drawRect:textRect];
hostView.backgroundColor = [UIColor whiteColor];
self.detailsView = hostView;
//self.detailsView.backgroundColor = [UIColor whiteColor];
NSLog(#"size: %f, %f", textRect.size.width, textRect.size.height);
NSLog(#"origin: %f, %f - size: %f, %f, backgroundColor: #%#", self.detailsView.frame.origin.x, self.detailsView.frame.origin.y, self.detailsView.frame.size.width, self.detailsView.frame.size.height, self.detailsView.backgroundColor);
[self.view addSubview:self.detailsView];
self.hostSays.text = textR;
self.hostSays.textColor = [UIColor blueColor];
[self.view layoutSubviews];
}
SOLUTION (ONLY 1 PART):
OK so I managed to solve half of my problems. I had to add the following code in my BubbleView class (inside - (id)initWithFrame:(CGRect)frame). This got rid of the square angles! (I think Wain was the one who suggested this but I might've misunderstood him)...
[self setOpaque:NO];
[self setBackgroundColor:[UIColor clearColor]];
So...still have the other part 2 of problem to solve and I'm hoping someone has run into this issue before!
Set the background colour of the view and add the label as a subview. Set the frame to get your required padding. Do not implement drawRect.
Now, the view will draw the background colour and the label automatically and the label will draw the text (with its background colour and border settings).
I know when I create custom buttons I need to setMasksToBounds
+ (void) addBorderToButtons:(UIButton *) btn
{
// Round button corners
CALayer *btnLayer = [btn layer];
[btnLayer setMasksToBounds:YES];
[btnLayer setCornerRadius:15.0f];
// Apply a 1 pixel, black border around Buy Button
[btnLayer setBorderWidth:1.5f];
[btnLayer setBorderColor:[[UIColor blackColor] CGColor]];
}
Setting this changes
To this
If you want to save your coding approach you strongly need to add [super drawRect:rect] in your drawRect: method
- (void)drawRect:(CGRect)rect{
[super drawRect:rect];
YOUR CODE
}
In this case you will see your text in UILabel.
Also you should not call drawRect: directly. It will be called automatically in runtime:
BubbleView *hostView =
[[BubbleView alloc] initWithFrame:CGRectMake(20.0f,
160.0f,
textRect.size.width+20,
textRect.size.height+20)];
hostView.bubbleWidth = textRect.size.width+20;
hostView.bubbleHeight = textRect.size.height+20;
hostView.text = textR;
// hostView.layer.cornerRadius = 10.0f;
// self.view.layer.masksToBounds = TRUE;
// [hostView drawRect:textRect];
// hostView.backgroundColor = [UIColor whiteColor];
self.detailsView = hostView;

Using a UIScrollview to zoom/pan an image, place items on top of image and move them

I am using a uiscrollview to display an UIImageview that is larger then screen size (just like photo viewing in the Photo Library). next i needed to add a point (i am using a UIImageview to show a dot) to the screen when the user taps. got that working.
now what i am trying to do is have that point to stay in the same location relative to the image. UIScrollview has some notifications for when dragging starts and ends, but nothing that gives a constant update of its contentoffset. say i place a dot at X location. i then scroll down 50 pixels, the point needs to move up 50 pixels smoothly (so the point always stays at the same location relative to the image).
does anybody have any ideas?
EDIT: adding code
- (void)viewDidLoad
{
[super viewDidLoad];
//other code...
scrollView.delegate = self;
scrollView.clipsToBounds = YES;
scrollView.decelerationRate = UIScrollViewDecelerationRateFast;
scrollView.minimumZoomScale = (scrollView.frame.size.width / imageView.frame.size.width);
scrollView.maximumZoomScale = 10.0;
//other code...
}
adding a point
-(void) foundTap:(UITapGestureRecognizer *) recognizer
{
CGPoint pixelPos = [recognizer locationInView:self.view];
UIImageView *testPoint = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"inner-circle.png"]];
testPoint.frame = CGRectMake(0, 0, 20, 20);
testPoint.center = CGPointMake(pixelPos.x, pixelPos.y);
[self.scrollView addSubview:testPoint];
NSMutableArray *tempTestPointArray = [[NSMutableArray alloc] initWithArray:testPointArray];
[tempTestPointArray addObject:testPoint];
testPointArray = tempTestPointArray;
NSLog(#"recorded point %f,%f",pixelPos.x,pixelPos.y);
}
getting pixel points
-(void)scrollViewDidZoom:(UIScrollView *)scrollView
{
NSLog(#"zoom factor: %f", scrollView.zoomScale);
UIPinchGestureRecognizer *test = scrollView.pinchGestureRecognizer;
UIView *piece = test.view;
CGPoint locationInView = [test locationInView:piece];
CGPoint locationInSuperview = [test locationInView:piece.superview];
NSLog(#"locationInView: %# locationInSuperView: %#", NSStringFromCGPoint(locationInView), NSStringFromCGPoint(locationInSuperview));
}
You can implement the UIScrollViewDelegate method scrollViewDidScroll: to get a continuous callback whenever the content offset changes.
Can you not simply add the image view with the dot as a subview of the scroll view?
You can use something like this:
UIGraphicsBeginImageContext(mainimg.frame.size);
[mainimg.image drawInRect:
CGRectMake(0, 0, mainimg.frame.size.width, mainimg.frame.size.height)];
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetLineCap(ctx, kCGLineCapButt);
CGContextSetLineWidth(ctx,2.0);
CGContextSetRGBStrokeColor(ctx, 1.0, 0.0, 0.0, 1.0);
CGContextBeginPath(ctx);
if (largecursor == FALSE) {
CGContextMoveToPoint(ctx, pt.x-3.0, pt.y);
CGContextAddLineToPoint(ctx, pt.x+3.0,pt.y);
CGContextMoveToPoint(ctx, pt.x, pt.y-3.0);
CGContextAddLineToPoint(ctx, pt.x, pt.y+3.0);
} else {
CGContextMoveToPoint(ctx, 0.0, pt.y);
CGContextAddLineToPoint(ctx, maxx,pt.y);
CGContextMoveToPoint(ctx, pt.x, 0.0);
CGContextAddLineToPoint(ctx, pt.x, maxy);
}
CGContextStrokePath(ctx);
mainimg.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Extending UIScrollView when it fills up with more content

Ok, so i got a scrollview to load when an user logs in to my application. When the user is authenticated, i need to create a scrollview programmatically. To do so, i have the following code:
[scrollView removeFromSuperview];
UIScrollView *view = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, applicationFrame.size.width, self.view.frame.size.height)];
view.backgroundColor = [UIColor greenColor];
//-- get the y-coordinate of the view
CGFloat viewCenterY = self.view.center.y;
//--calculate how much visible space is left
CGFloat freeSpaceHeight = applicationFrame.size.height - keyboardBounds.size.height;
//-- calculate how much the scrollview must scroll
CGFloat scrollAmount = viewCenterY - freeSpaceHeight / 2.0;
if(scrollAmount < 0) scrollAmount = 0;
//set the new scrollsize contentview
view.contentSize = CGSizeMake(applicationFrame.size.width, applicationFrame.size.height + keyboardBounds.size.height);
//scroll the scrollview
[view setContentOffset:CGPointMake(0, scrollAmount) animated:YES];
for(int v = 0; v < 15; v++){
CGFloat yCoord = v * 100;
UILabel *mijnLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, yCoord, 200, 50)];
mijnLabel.text = #"1337";
mijnLabel.font = [UIFont fontWithName:#"Verdana" size:20];
mijnLabel.textColor = [UIColor redColor];
[view addSubview:mijnLabel];
[mijnLabel release];
}
[self.view addSubview:view];
[view release];
}
How do i extend my view according to the amount of labels i added? I also want to know how i can make my scrollview fill up the entire screen.. My scrollview is now only filling up the screen when in portrait mode.
This is the login screen that gets removed:
[scrollView removeFromSuperview];
you need to keep track of numbers of label that you are adding into the scroll view. suppose if your label's height is 50 then take a variable and make a total of all label's height and give a new frame to your scroll view. like :
view.frame = CGRectmake(0,0,applicationFrame.size.width,totalHeightOfLabel);
[self.view addSubview:view];
[view release];
hope this will give a idea...

UIScroll view for comic App

I´m working on an ipad app for a comic but i can´t get my scroll view to work. I need it to do:
Pinch zoom
Rotation
Double tap and move by comic strip
Here´s an example of what i want to get http://vimeo.com/16073699 (Second 35 +-)
Right now i have pinch zoom but i can get the scroll view to rotate and center image.
Here´s my controller code:
#define ZOOM_VIEW_TAG 100
#define ZOOM_STEP 2
#define PAGE_TIME 10
- (void)viewDidLoad{
[super loadView];
self.myImage.image = [UIImage imageNamed:#"Tira01.jpg"];
[self.myImage setTag:ZOOM_VIEW_TAG];
UISwipeGestureRecognizer *recognizer;
recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(Tap)];
[(UITapGestureRecognizer *)recognizer setNumberOfTouchesRequired:1];
[(UITapGestureRecognizer *)drecognizer setNumberOfTapsRequired:1];
[[self myImage] addGestureRecognizer:recognizer];
[recognizer release];
self.drecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
[(UITapGestureRecognizer *)drecognizer setNumberOfTouchesRequired:1];
[(UITapGestureRecognizer *)drecognizer setNumberOfTapsRequired:2];
[[self myImage] addGestureRecognizer:drecognizer];
[drecognizer release];
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return [myScrollView viewWithTag:ZOOM_VIEW_TAG];
}
- (void)handleDoubleTap:(UIGestureRecognizer *)gestureRecognizer {
UIInterfaceOrientation currentOrientation = [[UIDevice currentDevice] orientation];
if(!self.zoomed)
{
// double tap zooms in
float newScale = [self.myScrollView zoomScale] * ZOOM_STEP;
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];
[self.myScrollView zoomToRect:zoomRect animated:YES];
self.zoomed = YES;
}
else {
float newScale = [self.myScrollView zoomScale] / ZOOM_STEP;
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];
[self.myScrollView zoomToRect:zoomRect animated:YES];
self.zoomed = NO;
}
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
return YES;
}
- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center {
CGRect zoomRect;
// the zoom rect is in the content view's coordinates.
// At a zoom scale of 1.0, it would be the size of the imageScrollView's bounds.
// As the zoom scale decreases, so more content is visible, the size of the rect grows.
zoomRect.size.height = [self.myScrollView frame].size.height / scale;
zoomRect.size.width = [self.myScrollView frame].size.width / scale;
// choose an origin so as to get the right center.
zoomRect.origin.x = center.x - (zoomRect.size.width / 2.0);
zoomRect.origin.y = center.y - (zoomRect.size.height / 2.0);
return zoomRect;
}
In interface builder i have:
-> UIView(ScaleToFill mode)
--> UIScrollView (ScaleToFill mode)
---> UIImageView (AspectFit mode)
I don´t know what i´m doing wrong but i´m going crazy with that :(
Regarding the UIScrollView centering the content, I might be wrong here, but the UIScrollView doesn't automatically do that.
In my app i'm manually doing it by actually moving the content in the scrollView so that it is centered.
Just as a quick explanation for the code below, if the content (image) frame is smaller than the bounds of the scroll view, then adjust the position of the content horizontally and vertically.
The code below is from my class derived from UIScrollView. If you're using the default UIScrollView, you can use this code in the parent UIView.
- (void)layoutSubviews
{
[super layoutSubviews];
if (![self centersContent])
{
return;
}
// center the image as it becomes smaller than the size of the screen
CGSize boundsSize = self.bounds.size;
CGRect frameToCenter = imageView.frame;
// center horizontally
if (frameToCenter.size.width < boundsSize.width)
frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2;
else
frameToCenter.origin.x = 0;
// center vertically
if (frameToCenter.size.height < boundsSize.height)
frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2;
else
frameToCenter.origin.y = 0;
imageView.frame = frameToCenter;
}

How do I center a UIImageView within a full-screen UIScrollView?

In my application, I would like to present the user with a full-screen photo viewer much like the one used in the Photos app. This is just for a single photo and as such should be quite simple. I just want the user to be able to view this one photo with the ability to zoom and pan.
I have most of it working. And, if I do not center my UIImageView, everything behaves perfectly. However, I really want the UIImageView to be centered on the screen when the image is sufficiently zoomed out. I do not want it stuck to the top-left corner of the scroll view.
Once I attempt to center this view, my vertical scrollable area appears to be greater than it should be. As such, once I zoom in a little, I am able to scroll about 100 pixels past the top of the image. What am I doing wrong?
#interface MyPhotoViewController : UIViewController <UIScrollViewDelegate>
{
UIImage* photo;
UIImageView *imageView;
}
- (id)initWithPhoto:(UIImage *)aPhoto;
#end
#implementation MyPhotoViewController
- (id)initWithPhoto:(UIImage *)aPhoto
{
if (self = [super init])
{
photo = [aPhoto retain];
// Some 3.0 SDK code here to ensure this view has a full-screen
// layout.
}
return self;
}
- (void)dealloc
{
[photo release];
[imageView release];
[super dealloc];
}
- (void)loadView
{
// Set the main view of this UIViewController to be a UIScrollView.
UIScrollView *scrollView = [[UIScrollView alloc] init];
[self setView:scrollView];
[scrollView release];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Initialize the scroll view.
CGSize photoSize = [photo size];
UIScrollView *scrollView = (UIScrollView *)[self view];
[scrollView setDelegate:self];
[scrollView setBackgroundColor:[UIColor blackColor]];
// Create the image view. We push the origin to (0, -44) to ensure
// that this view displays behind the navigation bar.
imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, -44.0,
photoSize.width, photoSize.height)];
[imageView setImage:photo];
[scrollView addSubview:imageView];
// Configure zooming.
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
CGFloat widthRatio = screenSize.width / photoSize.width;
CGFloat heightRatio = screenSize.height / photoSize.height;
CGFloat initialZoom = (widthRatio > heightRatio) ? heightRatio : widthRatio;
[scrollView setMaximumZoomScale:3.0];
[scrollView setMinimumZoomScale:initialZoom];
[scrollView setZoomScale:initialZoom];
[scrollView setBouncesZoom:YES];
[scrollView setContentSize:CGSizeMake(photoSize.width * initialZoom,
photoSize.height * initialZoom)];
// Center the photo. Again we push the center point up by 44 pixels
// to account for the translucent navigation bar.
CGPoint scrollCenter = [scrollView center];
[imageView setCenter:CGPointMake(scrollCenter.x,
scrollCenter.y - 44.0)];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[[self navigationController] navigationBar] setBarStyle:UIBarStyleBlackTranslucent];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent animated:YES];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[[[self navigationController] navigationBar] setBarStyle:UIBarStyleDefault];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return imageView;
}
#end
This code should work on most versions of iOS (and has been tested to work on 3.1 upwards).
It's based on the Apple WWDC code for PhotoScroller.
Add the below to your subclass of UIScrollView, and replace tileContainerView with the view containing your image or tiles:
- (void)layoutSubviews {
[super layoutSubviews];
// center the image as it becomes smaller than the size of the screen
CGSize boundsSize = self.bounds.size;
CGRect frameToCenter = tileContainerView.frame;
// center horizontally
if (frameToCenter.size.width < boundsSize.width)
frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2;
else
frameToCenter.origin.x = 0;
// center vertically
if (frameToCenter.size.height < boundsSize.height)
frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2;
else
frameToCenter.origin.y = 0;
tileContainerView.frame = frameToCenter;
}
Have you checked out the UIViewAutoresizing options?
(from the documentation)
UIViewAutoresizing
Specifies how a view is automatically resized.
enum {
UIViewAutoresizingNone = 0,
UIViewAutoresizingFlexibleLeftMargin = 1 << 0,
UIViewAutoresizingFlexibleWidth = 1 << 1,
UIViewAutoresizingFlexibleRightMargin = 1 << 2,
UIViewAutoresizingFlexibleTopMargin = 1 << 3,
UIViewAutoresizingFlexibleHeight = 1 << 4,
UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};
typedef NSUInteger UIViewAutoresizing;
Are you using IB to add the scroll view? Change the autosizing options of the scrollview to the attached image.
I think the reason behind it is because the zoomScale applies to the whole contentSize, regardless of the actual size of the subview inside the scrollView (in your case it's an imageView). The contentSize height seems to be always equal or greater than the height of the scrollView frame, but never smaller. So when applying a zoom to it, the height of the contentSize gets multiplied by the zoomScale factor as well, that's why you're getting an extra 100-something pixels of vertical scroll.
You probably want to set the bounds of the scroll view = bounds of the image view, and then center the scroll view in its containing view. If you place a view inside a scroll view at an offset from the top, you will get that empty space above it.