problem with changing view - objective-c

hi I have a problem I made an application based on apples sample app called photoscroller and i want to add a login screen.but when i add it the showed view move upward 10-15 pixels and the main window is visible underneath.I ask why?
Parts of my code:
at view did load:
InfoViewController *infoView = [[InfoViewController alloc] initWithNibName:nil bundle:nil];
self.view = infoView.view;
[infoView release];
then later after validating the login:
CGRect pagingScrollViewFrame = [self frameForPagingScrollView];
pagingScrollView = [[UIScrollView alloc] initWithFrame:pagingScrollViewFrame];
pagingScrollView.pagingEnabled = YES;
pagingScrollView.backgroundColor = [UIColor blackColor];
pagingScrollView.showsVerticalScrollIndicator = NO;
pagingScrollView.showsHorizontalScrollIndicator = NO;
pagingScrollView.contentSize = [self contentSizeForPagingScrollView];
pagingScrollView.delegate = self;
self.view = pagingScrollView;
...
I do not know why is pushed upward when i add other view.
thank for every answer

Could you past the method - (CGRect) frameForPagingScrollView, without that method it's bit harder to understand your code.
But i guess the self.view.frame and the CGRect returned from that method differ.
Further guess would be, that the difference are not 10-15 pixels, but 20 pixels (for the height of the UIStatusBar), which might be enabled in your .xib-File but is actually not displayed.

Related

Animating a UIImageView with a mask but the mask is static

I am trying to have an animation in which a mask is placed in the center of the view. Any image view that passes behind the mask appears. So here is my code so far, but the problem with this code is that it animates the mask with the image view.
UIView *maskView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.worldImageView.frame.size.height, self.worldImageView.frame.size.height)];
// ...position maskView...
maskView.layer.position = CGPointMake(CGRectGetMidX([self.view bounds]), CGRectGetMidY([self.view bounds]));
maskView.layer.backgroundColor = [UIColor blackColor].CGColor;
maskView.layer.cornerRadius = 90;
self.worldImage = [[UIImageView alloc] init];
self.worldImage.frame = self.worldImageView.frame;
self.worldImage.image = [UIImage imageNamed:#"continents.png"];
[maskView addSubview:self.worldImage];
[self.view addSubview:maskView];
CABasicAnimation* worldAnimation = [[CABasicAnimation alloc] init];
[worldAnimation setFromValue:[NSValue valueWithCGPoint:CGPointMake(self.view.frame.size.width + 50, CGRectGetMidY([maskView bounds]))]];
[worldAnimation setToValue:[NSValue valueWithCGPoint:CGPointMake(-50, CGRectGetMidY([maskView bounds]))]];
worldAnimation.keyPath = #"position";
worldAnimation.duration = 6.0f;
worldAnimation.repeatCount = HUGE_VALF;
[[self.worldImage layer] addAnimation:worldAnimation forKey:nil];
I don't know if I explained this well enough. Please tell me if you need more info. Thank you in advance!
Your issue here is that the mask property of UIView is attached to that UIView - they can't move separately. Technically, it's actually attached to the view's underlying layer, but whatever.
If you want the image to appear as if it's passing in front of a circular window (so that you can see it as it goes by) you'll need to add it as a subview of the view with the mask. So, you might do something like this:
UIView *maskView = [[UIView alloc] init];
// ...position maskView...
maskView.layer.cornerRadius = 90;
maskView.clipsToBounds = YES;
self.worldImage = [[UIImageView alloc] init];
self.worldImage.frame = self.worldImageView.frame;
self.worldImage.image = [UIImage imageNamed:#"continents.png"];
[maskView addSubview:self.worldImage];
[self.view addSubview:maskView];
// ...animate worldImage back and forth...
Note that instead of using a CAShapeLayer, I simply put rounded corners on maskView; since you want a circular mask, it's a much simpler trick. Also, when animating worldImage, consider using one of UIView's block-based animation methods – they're a lot easier to handle for simple stuff like this.

UIScrollView metro theme

I am attempting to create a "metro" styled UIScrollView. It is similar to how iTunes app handles panels in the new ios version which wont be named.
I can't figure out how to have my views layout/scroll so that the next view in the sequence shows up. I've tried all sorts of things like keeping the contentSize the screen width but moving each view over -10ish so it will show up like above. I've tried making scrollView whose bounds were smaller than the screen so it would show the part of the next view. Nothing works.
Here is diagram of what I'm trying to do:
It seems extremely trivial on paper but I can't seem to get it work.
I'm not sure if I'm misinterpreting your requirements - but this might be a starting point to see how you could set it up:
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect viewBounds = self.view.bounds;
CGRect scrollViewFrame = CGRectMake(0, 0, floorf(CGRectGetWidth(viewBounds) / 2.2), CGRectGetHeight(viewBounds));
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:scrollViewFrame];
scrollView.center = self.view.center;
scrollView.contentSize = CGSizeMake(CGRectGetWidth(viewBounds) * 3, CGRectGetHeight(viewBounds) * 3);
scrollView.pagingEnabled = YES;
scrollView.clipsToBounds = NO;
UIPanGestureRecognizer *gestureRecognizer = scrollView.panGestureRecognizer;
[self.view addGestureRecognizer:gestureRecognizer];
for (int i = 0; i < 3; i++) {
CGRect frame = CGRectMake(10.f + (i * CGRectGetWidth(scrollView.bounds)), 10.f, CGRectGetWidth(scrollView.bounds) - 20.f, (CGRectGetHeight(scrollViewFrame) * 3) - 20.f);
UIView *view = [[UIView alloc] initWithFrame:frame];
view.backgroundColor = [UIColor redColor];
[scrollView addSubview:view];
}
[self.view addSubview:scrollView];
}
Literally just put this in an empty viewController's viewDidLoad:
The key things to note are
contentSize needs to be wide enough for all the panels
clipsToBounds should be NO so you can see the additional views
The bounds of the scrollview is essentially the main view port
pagingEnabled should be set
I've grabbed the panGestureRecognizer from the scrollview and attached it to the containing view instead so that panning is detected in the bounds of the containing view (which is larger) otherwise you are restricted to only detecting scrolls within the scrollviews bounds

ContentOffset and back to Top issue

I have a scrollView with paging. I declare it:
if(_fullPosterScroll == nil) _fullPosterScroll = [[UIScrollView alloc] initWithFrame:rc];
[_fullPosterScroll setDelegate:self];
[_fullPosterScroll setBackgroundColor:[UIColor blackColor]];
[_fullPosterScroll setCanCancelContentTouches:NO];
_fullPosterScroll.indicatorStyle = UIScrollViewIndicatorStyleWhite;
_fullPosterScroll.clipsToBounds = NO;
_fullPosterScroll.pagingEnabled = YES;
_fullPosterScroll.alwaysBounceHorizontal = NO;
_fullPosterScroll.directionalLockEnabled = YES;
And after a tap i call a method:
[_fullPosterScroll setContentOffset:CGPointMake(_selectedPosterPosition*(_fullPosterScroll.frame.size.width), 0) animated:YES];
NSLog(#"%f",_fullPosterScroll.contentOffset.y);
Why after that in Log i have for example 225.00 ?! This should be 0!
I can't see anything wrong with the code you've posted, but you should check to make sure that setContentOffset isn't triggering any delegate methods that are changing offset.
Also, Apple have a sample project, PageControl, that does exactly what you want, so you should look at that if you want a complete example.

applicationMusicPlayer volume notification

I am using an applicationMusicPlayer and when i try to change the volume appear the visual notification, as shown in the picture.
Here the code I am using:
[MPMusicPlayerController applicationMusicPlayer] setVolume:newVolune];
Anyone knows how to hide this notification?
I don't know where the docs says so, but if you add a MPVolumeView view to your app the system volume overlay goes away. Even if it is not visible:
- (void) viewDidLoad
{
[super viewDidLoad];
MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame: CGRectZero];
[self.view addSubview: volumeView];
[volumeView release];
...
}
You can use the hardware volume buttons, the setVolume method or directly interact with the control (if visible) that the overlay doesn't show up.
For iOS6 I had to set an image with alpha 0 and non-zero size to the MPVolumeView's image fields in order to get the default volume change notification to disappear.
// hide the hardware volume slider
UIImage *thumb = [[UIImage alloc] initWithCIImage:[UIImage imageNamed:#"volumeHider"].CIImage scale:0.0 orientation:UIImageOrientationUp];
MPVolumeView *hwVolume = [[MPVolumeView alloc] initWithFrame:self.frame];
[hwVolume setUserInteractionEnabled:NO];
hwVolume.showsRouteButton = NO;
[hwVolume setVolumeThumbImage:thumb forState:UIControlStateNormal];
[hwVolume setMinimumVolumeSliderImage:thumb forState:UIControlStateNormal];
[hwVolume setMaximumVolumeSliderImage:thumb forState:UIControlStateNormal];
[self addSubview:hwVolume];
This made the MPVolumeView be "visible" on the screen, but invisible to the user.
I encountered the same issue recently. Instead of adding the MPVolumeView to current view controller's view, I add it to the application's window once at the start of the app:
CGRect rect = CGRectMake(-500, -500, 0, 0);
MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:rect];
[self.window addSubview:volumeView];
This works in both iOS 7 and 8.
Swift 3
You can hide the System MPVolumeView using
override func viewDidLoad() {
super.viewDidLoad()
let volumeView = MPVolumeView(frame: CGRect.zero)
self.view.addSubview(volumeView)
}
I had success with this in iOS 6. Although it wouldn't perform well. It caused quite a bit of lag when sliding the thumbImage. I did have to take out the last 2 lines of code in order for this to work.
[volumeView release];
...
For me, on iOS 7, none of above solutions worked. Here is how I did it:
_volume = [[MPVolumeView alloc] initWithFrame: CGRectMake(-100,-100,16,16)];
_volume.showsRouteButton = NO;
_volume.userInteractionEnabled = NO;
[self.view addSubview:_volume];
[_volume release];
That is, simply set MPVolumeView's frame to an off-screen location such as (-100,-100).

Leak when adding subview

So Instruments tells me I have three memory leaks originating in this method (specifically, it points out the line:
[self.view addSubview:menuBar.view];
I can't see a leak and am racking my brains. I'm keeping a reference to the menuBar object and am releasing it. Anyone smarter than me that can explain? Is it a coincidence that I have three menubar items in my XIB and I'm getting three leaks?
Here is the entire method:
//
root vc calls to toggle display state of menu bar on screen
-(IBAction) showToolBar {
//if no toolbar exists, create one and add it to the view
if (!menuBarView) {
MenuBarViewController *menuBar = [[MenuBarViewController alloc] initWithNibName:#"MenuBarViewController" bundle:nil];
menuBar.book = self.selectedTitleDeck;
menuBar.booksArray = self.allTitleDeck;
self.menuBarView = menuBar;
[self.view addSubview:menuBar.view];
[menuBar release];
}
CGRect frame = menuBarView.view.frame;
[UIView beginAnimations:nil context:NULL];
if (self.toolBarIsDisplayed == NO) {
//show the toolbar
frame.origin.y = 725;
self.toolBarIsDisplayed = YES;
} else if (self.toolBarIsDisplayed == YES) {
//hide the toolbar
frame.origin.y = 788;
self.toolBarIsDisplayed = NO;
}
self.menuBarView.view.frame = frame;
[UIView commitAnimations];
}
addSubview: retains the view passed into it (see the reference). Once you call addSubView, you can release that view, like:
MenuBarViewController *menuBar = [[MenuBarViewController alloc] initWithNibName:#"MenuBarViewController" bundle:nil];
menuBar.book = self.selectedTitleDeck;
menuBar.booksArray = self.allTitleDeck;
self.menuBarView = menuBar;
[self.view addSubview:menuBar.view];
[menuBar.view release];
[menuBar release];
}
Show us what happens in MenuBarViewController's dealloc method. I suspect you are forgetting to release its instance variables.
As suggested in the comments to my question, the problem was not in the code but in running my app in the simulator and trying to detect memory leaks.
When Instruments is run against the code on the device, no leaks are reported.
My consolation prize is a far more profound understanding of memory management unearthed in two days of trying to locate a leak that didn't exist.
Thanks to all for your advice, much appreciated.