So i want to add subview (UIImageView) to my main view with the following code:
NSString *fileLocation = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:#"background_main.png"];
_aImage = [[UIImage alloc] initWithContentsOfFile:fileLocation];
_aImageView = [[UIImageView alloc] initWithImage:_aImage];
_aImageView.frame = CGRectMake(-200, 0, _aImage.size.width, _aImage.size.height);
[self.view addSubview:_aImageView];
as you can see - i'm adding UIImageView to position (-200;0);
But it shows up at default position : (0;0).
My view hierarchy:
self.view -main view where i'm adding subview(UIImageView);
_aImageView - UIImageView that i'm adding.
Results:
NSLog(#"image is %#",_aImageView); //result (-200 0; 420 568)
CGPoint test = [_aImageView convertPoint:_aImageView.frame.origin toView:self.view];
NSLog(#"convert %f %f",test.x,test.y); //result (-400.000000; 0.000000)
I know that position is still (0;0) because i can see it when i testing my app. Later when i'm changing position of _aImageView to (-50;0) it's shows black screen. I know i'm missing something very important but i can't figure out why it shows up at (0;0) position.
Links to similar questions that i have checked:
How to addSubview with a position?
iOS: Add subview with a fix position on screen
what worked for me in the past in this situations is doing something like this :
NSString *fileLocation = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:#"background_main.png"];
_aImage = [[UIImage alloc] initWithContentsOfFile:fileLocation];
_aImageView = [[UIImageView alloc] initWithImage:CGRectMake(-200, 0, _aImage.size.width, _aImage.size.height)];
[_aImageView setImage:_aImage];
[self.view addSubview:_aImageView];
If this doesn't work try changing it's frame in viewDidAppear method (i assume you're adding it in viewDidLoad).
Last solution is to set the view's center after you add it on the screen.
CGPoint pt=CGPointMake(-200+_aImageView.frame.size.width/2,_aImageView.frame.size.height/2);
_aImageView.center=pt;
If that fails the view is changed in another part of your code or the view is added on the screen properly but the image is nil.
I believe you can't change the frame until in layoutSubviews. You could set the frame in layoutSubviews...
-(void)layoutSubviews
{
[_aImageView setFrame:CGRectMake(-200, 0, _aImage.size.width, _aImage.size.height)];
}
Or set the frame first then add the image wherever you're initializing the UIImageView...
_aImageView = [[UIImageView alloc] initWithFrame:CGRectMake(-200, 0, _aImage.size.width, _aImage.size.height];
[_aImageView setImage:_aImage];
Related
So I have seen the many other posts on this, and I think I have tried almost all of them. I don't want this to be a duplicate, but I can't get a solution to my problem. I have a setup like this:
When I get to my Scroll View Controller, I can page over just fine, but I can also move the pictures around vertically. I think it has something to do with the NavigationBar forcing the ScrollView frame down, but still having the frame set to the full screen size. How do I prevent any vertical scrolling on the Scroll View View Controller? My .m is below:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.navigationController.navigationBarHidden = NO;
i = 0;
_PhotoBundle = [[NSBundle mainBundle] pathsForResourcesOfType:#".jpg"inDirectory:#"Dog_Images"];
_PhotoArray = [[NSMutableArray alloc] initWithCapacity:_PhotoBundle.count];
for (NSString* path in _PhotoBundle)
{
[_PhotoArray addObject:[UIImage imageWithContentsOfFile:path]];
}
for (int x = 0; x < _PhotoArray.count; x++)
{
CGRect frame;
frame.origin.x = self.mainScroll.frame.size.width * x;
frame.origin.y = 0;
frame.size = self.mainScroll.frame.size;
UIImage *nextImg = [[UIImage alloc] init];
nextImg = [_PhotoArray objectAtIndex:x];
UIImageView *nextIV = [[UIImageView alloc] initWithFrame:frame];
[nextIV setImage:nextImg];
[self.mainScroll addSubview:nextIV];
//NSLog(#"Pass %d", x);
}
self.mainScroll.contentSize = CGSizeMake(self.mainScroll.frame.size.width * _PhotoArray.count, self.mainScroll.frame.size.height);
}
Thank you very much!!
So I found a post that explained it perfectly:
How to disable just vertical scrolling in a UIScrollView?
When I change my
CGSizeMake(self.mainScroll.frame.size.width * _PhotoArray.count, self.mainScroll.frame.size.height);
to
CGSizeMake(self.mainScroll.frame.size.width * _PhotoArray.count, 1.0);
It makes the contentSize from being larger than the bounds... Something that I have read about, but did not fully understand. I hope this helps someone else who is stuck with this...
UIScrollView scrolls it's content only if it's -contentSize is set bigger than it's frame. So when you are setting self.mainScroll.contentSize it has contentSize.height more that it's frame.
Try reading at least Apple's documentation before using it's classes. It's boring. But salary pays off all the boring stuff.
By the way. You are using UIScrollView incorrectly for your displaying UIImageView objects. Try to watch Apple WWDC sessions (which could be downloaded from iTunes) - there are two or three sessions about how to use just three UIImageView objects to draw an endless UIScrollView paging
Apple's documentation on UIScrollView
I am presenting a modal view with a UIImageView set to content mode fill scale (via the xib). I am setting a UIImage in the modal view class with a thumbnail from the parent class :
NSURL * finishedMovie = [self applicationDocumentsDirectory:#"FinishedVideo.mov"];
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:finishedMovie];
UIImage *thumbnail = [player thumbnailImageAtTime:1.0 timeOption:MPMovieTimeOptionNearestKeyFrame];
previewScreen = [[PreviewScreenViewController alloc]initWithNibName:#"PreviewScreenViewController" bundle:nil];
previewScreen.thumbnailImage = thumbnail;
[self presentModalViewController:previewScreen animated:YES];
Then in the modal view class itself :
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
previewImageBox.image = thumbnailImage;
}
The problem is that when the view appears, it seems to be ignoring the content mode set in the xib and just inserting the image at full size.
This seems like a bug, as when I return to this view the image fits in the UIImage view properly.
Can anyone help ?
Thanks.
OK solved it ! If you manually create the UIImageView in code, it seems to work.
// Do any additional setup after loading the view from its nib.
//Work around to solve bug in UIToolkit where aspect ratio is ignored when view loads.
imageView = [[UIImageView alloc] initWithFrame:CGRectMake(13, 87, 294, 164)];
//Set the image to our thumbnail.
[self.view addSubview:imageView];
More than likely you have the clipsToBounds property set to NO. This will prevent the UIImageView from clipping content outside of its rect. You can set the borderColor of the UIImageView layer to see if this is actually happening.
Basically, I want to have an app with only one view that has an image on it. I want to be able to swipe left or right and have the first image go out of the view and the second image to come in. The images are the same and I want it to look like they are connected (like scrolling down a rope where the pattern just repeats, but it looks like a constant scroll). I need it to be able to change the image or restart after a series of swipes. I know that I need to turn pagination ON in the UIScrollView, but I am new to iOS and am having trouble.
Ultimately, I want to have the iPhone vibrate every so-and-so swipes (and restart the pattern).
I'm sure that there are a lot of ways to do this (i.e. a TableView) so feel free to just point me in the direction of some references if the answer is tedious to explain.
Thanks!
FOLLOW UP:
I found an Apple example that did very nearly what I wanted to do. I made a lot of adjustments to it, but I'm banging my head against a wall trying to get the images to cycle. Here is what I think is the offending code, but I'm not sure what the solution is, as the ScrollView is functional, it just doesn't reset the center to the current view. Any ideas?
- (void)layoutScrollImages
{
UIImageView *view = nil;
NSArray *subviews = [scrollView1 subviews];
// reposition all image subviews in a horizontal serial fashion
CGFloat curXLoc = 0;
for (view in subviews)
{
if ([view isKindOfClass:[UIImageView class]] && view.tag > 0)
{
CGRect frame = view.frame;
frame.origin = CGPointMake(curXLoc, 0);
view.frame = frame;
curXLoc += (kScrollObjWidth);
}
}
// set the content size so it can be scrollable
[scrollView1 setContentSize:CGSizeMake((kNumImages * kScrollObjWidth), [scrollView1 bounds].size.height)];
}
I'd just use a UIScrollView. Set the contentWidth to be 3 times the width/height of the view (for 3 pages) and set the contentOffset to be the center 'page' (view.bounds.size.width or view.bounds.size.height depending on whether you're scrolling horizontally/vertically respectively) . You'll need to setup a delegate for the UIScrollView (probably the view controller) and implement - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView. This will be called when the scroll view has finished decelerating. Once it has finished decelerating, reset the contentOffset back to the center view. This should give the impression of an infinite scroll. You can also set a counter to increment in the scrollViewDidEndDecelerating method to increment the counter or initiate the vibration.
You shouldn't need to keep repositioning the images. Just set the images once in the scrollView:
//Horizontal arrangement
UIImage *image = [UIImage imageNamed:#"nameOfImage.png"];
UIImageView *imageView1 = [[UIImageView alloc] initWithImage:image];
UIImageView *imageView2 = [[UIImageView alloc] initWithImage:image];
UIImageView *imageView3 = [[UIImageView alloc] initWithImage:image];
NSArray *imageViews = [NSArray arrayWithObjects:imageView1, imageView2, imageView3];
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
[self.view addSubview: scrollView]; //This code assumes it's in a UIViewController
CGRect cRect = scrollView.bounds;
UIImageView *cView;
for (int i = 0; i < imageViews.count; i++){
cView = [imageViews objectAtIndex:i];
cView.frame = cRect;
[scrollView addSubview:cView];
cRect.origin.x += cRect.size.width;
}
scrollView.contentSize = CGSizeMake(cRect.origin.x, scrollView.bounds.size.height);
scrollView.contentOffset = CGPointMake(scrollView.bounds.size.width, 0); //should be the center page in a 3 page setup
So the images are setup, you don't need to mess with them anymore. Just reset the contentOffset when the scroll views stops (note: you need to make sure you're the delegate of the scroll view or you'll not receive the message when the scroll view stops):
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
scrollView.contentOffset = CGPointMake(scrollView.bounds.size.width, 0);
}
Please forgive any typos. I wrote it out by hand.
Look on cocoacontrols.com for a custom photo album view. As for the vibration, this code snippet vibrates the phone (make sure you link to and #import <AudioToolbox/AudioToolbox.h>):
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
In my application,i created an imageview on the above the tabbar.I want to display some images here for displaying some adds there.
What my actual problem is...i added this on my table view and whenever i am scrolling the table view ,my imageview is also scrolling.Please help me in this
Thanks in advance.Here is my code
UIImageView *currentLocationImageView = [[UIImageView alloc] init];
NSURL *url1 = [NSURL URLWithString:#"http://imgsrv.995themountain.com/image/kqmt2/UserFiles/Image/SiteGraphics/MTNVideos360x80.jpg"];
UIImage *img1 = [UIImage imageWithData: [NSData dataWithContentsOfURL:url1]];
NSURL *url2 = [NSURL URLWithString:#"http://download.xbox.com/content/images/35f6c527-fb73-40d3-bcb9-bdea2680bc03/1033/banner.png"];
UIImage *img2 = [UIImage imageWithData: [NSData dataWithContentsOfURL:url2]];
NSArray *images = [NSArray arrayWithObjects:img1, img2, nil];
[currentLocationImageView setAnimationImages:images];
[currentLocationImageView setAnimationRepeatCount:0];
[currentLocationImageView setAnimationDuration:5.0];
currentLocationImageView.frame = CGRectMake(0.0, 340.0, 320.0, 30.0);
//self.tableView.tableFooterView = currentLocationImageView;
[currentLocationImageView startAnimating];
[self.view addSubview:currentLocationImageView];
Without seeing more code, it looks as though you may be using a UITableViewController instead of a UIViewController. The difference between the two is important in the case of your last line [self.view addSubview:currentLocationImageView]. What that does in a UIViewController is adds it to the view that would be containing the tableview and the imageview. However, in a UITableViewController the self.view property holds the tableview itself, therefor, it ads your image view as a subview of the tableview, subjecting it to the tableview's scrolling behaviour.
What you can do is change from using a UITableViewController (probably going to be trivial for your application, but may be less than trivial depending on why you opted to use it in the first place); and you'll also need to explicitly create the tableview, and add it to the backing view of the UIViewController subclass you're writing—akin to how you're adding the imageview above.
Hope this helps.
I am a beginner at Obj-C/Cocoa Touch/iPhone OS.
I wish to have a background for my app with different images everytime the the view is called.
Say I have 10 images. I 've used it like this:
//random image generation
NSString* imageName;
int aRandomNumber = arc4random() % 10;
imageName =[NSString stringWithFormat:#"g%d.jpg",aRandomNumber];
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:imageName]]];
NSLog(#"aRandomNumber is %d", aRandomNumber);
//random image is generated
Its working fine
Now, say I have text labels on my view and the text isn't displaying correctly due to image colors.
How can I make it a little transparent? (I guess in Interface Builder its called alpha.)
Say my image isn't 320x480. How do I set it to fill the entire view?
How can I do it with UIView/UIImageView?
I found initWithHue:saturation:brightness:alpha: in the documentation but it's not working:
self.view.backgroundColor = [[UIColor alloc] initWithHue:0.0 saturation:1.0 brightness:1.0 alpha:1.0];
Please Help!
A friend suggested........
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:imageName]]];
..........he told it's more efficient because it doesn't save the image in the cache.
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"imageName.png"]];
more info with example project
Besides all of the other responses here, I really don't think that using backgroundColor in this way is the proper way to do things. Personally, I would create a UIImageView and insert it into your view hierarchy. You can either insert it into your top view and push it all the way to the back with sendSubviewToBack: or you can make the UIImageView the parent view.
I wouldn't worry about things like how efficient each implementation is at this point because unless you actually see an issue, it really doesn't matter. Your first priority for now should be writing code that you can understand and can easily be changed. Creating a UIColor to use as your background image isn't the clearest method of doing this.
use this
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"Default"]];
simple way :
-(void) viewDidLoad {
self.view.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"background.png"]];
[super viewDidLoad];
}
It's a very bad idea to directly display any text on an irregular and ever changing background. No matter what you do, some of the time the text will be hard to read.
The best design would be to have the labels on a constant background with the images changing behind that.
You can set the labels background color from clear to white and set the from alpha to 50.0 you get a nice translucent effect. The only problem is that the label's background is a stark rectangle.
To get a label with a background with rounded corners you can use a button with user interaction disabled but the user might mistake that for a button.
The best method would be to create image of the label background you want and then put that in an imageview and put the label with the default transparent background onto of that.
Plain UIViews do not have an image background. Instead, you should make a UIImageView your main view and then rotate the images though its image property. If you set the UIImageView's mode to "Scale to fit" it will scale any image to fit the bounds of the view.
You want the background color of your main view to be semi-transparent? There's nothing behind it... so nothing will really happen however:
If you want to modify the alpha of any view, use the alpha property:
UIView *someView = [[UIView alloc] init];
...
someView.alpha = 0.8f; //Sets the opacity to 80%
...
Views themselves have the alpha transparency, not just UIColor.
But since your problem is that you can't read text on top of the images... either:
[DESIGN] Reconsider the design/placement of the images. Are they necessary as background images? What about the placement of the labels?
[CODE] It's not exactly the best solution, but what you could do is create a UIView whose frame takes up the entire page and add some alpha transparency to it. This will create an "overlay" of sorts.
UIView *overlay = [[[UIView alloc] init] autorelease];
overlay.frame = self.view.bounds;
overlay.alpha = 0.2f;
[self.view addSubview:overlay];
... Add the rest of the views
You can set multiple background image in every view using custom method as below.
make plist for every theam with background image name and other color
#import <Foundation/Foundation.h>
#interface ThemeManager : NSObject
#property (nonatomic,strong) NSDictionary*styles;
+ (ThemeManager *)sharedManager;
-(void)selectTheme;
#end
#import "ThemeManager.h"
#implementation ThemeManager
#synthesize styles;
+ (ThemeManager *)sharedManager
{
static ThemeManager *sharedManager = nil;
if (sharedManager == nil)
{
sharedManager = [[ThemeManager alloc] init];
}
[sharedManager selectTheme];
return sharedManager;
}
- (id)init
{
if ((self = [super init]))
{
}
return self;
}
-(void)selectTheme{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *themeName = [defaults objectForKey:#"AppTheme"] ?: #"DefaultTheam";
NSString *path = [[NSBundle mainBundle] pathForResource:themeName ofType:#"plist"];
self.styles = [NSDictionary dictionaryWithContentsOfFile:path];
}
#end
Can use this via
NSDictionary *styles = [ThemeManager sharedManager].styles;
NSString *imageName = [styles objectForKey:#"backgroundImage"];
[imgViewBackGround setImage:[UIImage imageNamed:imageName]];