UIBarButtonItem textures offset when iPhone only app is run on iPad - objective-c

In the main view of my app, I instantiate 3 UIBarButtonItem(2 actual buttons and 1 flexible spacer) with custom images (created using [UIImage imageNamed:]), then set them as the items of a UIToolBar. Here's the code:
-(void)viewDidLoad{
[super viewDidLoad];
UIToolbar *menuBar = [UIToolbar new];
menuBar.barStyle = UIBarStyleDefault;
CGRect viewBounds = [UIScreen mainScreen].bounds;
//menuBar is rotated to be viewed vertically along the right side of the device in portrait orientation, the app does not support device rotation
menuBar.transform = CGAffineTransformRotate(menuBar.transform, M_PI * 0.5f);
[menuBar setFrame:CGRectMake(viewBounds.size.width - menuBarHeight, 5, menuBarHeight, viewBounds.size.height)];
[self.view addSubview:menuBar];
[menuBar release];
UIBarButtonItem
*peekButton = [[UIBarButtonItem alloc]
initWithImage:[UIImage imageNamed:#"peekIcon.png"]
style:UIBarButtonItemStyleDone
target:self
action:#selector(peek:)],
*pauseButton = [[UIBarButtonItem alloc]
initWithImage:[UIImage imageNamed:#"pauseIcon.png"]
style:UIBarButtonItemStyleDone
target:self
action:#selector(pauseGame:)],
*flexSpace = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil];
menuBar.items = #[flexSpace, pauseButton, peekButton];
[flexSpace release];
[pauseButton release];
[peekButton release];
}
When run on a iPod touch running iOS 5.1, the toolBar and buttons appear as expected, like so:
but when run on an iPad(iOS 4.3), the textures look like this:
I can not seem to discern the cause, however, I believe it may be an OS, or device specific bug, as I keep encountering similarly obscure graphics issues where UI elements are drawn with total disregard for the underlaying object's data. Unfortunately I can't find any relevant docs (Apple or other wise) to shed some light on this issue.
Any input is greatly appreciated, thanks.

The issue seems to arise from calling UINavigationController's method
-(void)pushViewController:(UIViewController*)viewController animated:(BOOL)animated;
As screen transitions were not originally intended to be animated, the animated argument was NO. Changing the value to YES seems to be the solution.
This also seems to have solved some other graphics issues I was experiencing.

Related

Right bar button item not aligned vertically

I am setting a rightbarbuttonitem in from a viewController using the following code:
UIBarButtonItem *item = [[UIBarButtonItem alloc]initWithTitle:#"Save" style:UIBarButtonItemStylePlain target:self action:#selector(saveDetails)];
self.navigationItem.rightBarButtonItem = item;
It is appearing as shown in the image:
As you can see, the button which appears is not vertically aligned with either th leftbuttonitem or the title.
I also tried adjusting the alignment using the code mentioned here:
[self.navigationItem.rightBarButtonItem setTitlePositionAdjustment:UIOffsetMake(0, -10) forBarMetrics:UIBarMetricsDefault];
But this removes the custom font and moves the button even higher.
How can I set a rightbarbuttonitem which is aligned AND maintains the custom font set using the UIAppearance proxy?
EDIT:
I even tried using
[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:#selector(saveDetails)];
but the result is exactly as shown in the first image.
UPDATE (Sep 20):
It seems that I will have to go with Alexander's answer, anybody with a cleaner solution?
You can use the next variant:
UIButton *saveButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 80, 20)];
[saveButton addTarget:self action:#selector(saveDetails) forControlEvents:UIControlEventTouchUpInside];
[saveButton setTitle: #"Save" forState:UIControlStateNormal];
[saveButton setTitleEdgeInsets:UIEdgeInsetsMake(5, 0, 0, 0)];
UIBarButtonItem *item =[[UIBarButtonItem alloc] initWithCustomView:saveButton];
self.navigationItem.rightBarButtonItem = item;
I tried the answer but didn't seem to work.
The solution for me was adding UIButton as UIBarButtonItem. If it sounds confusing, just drag a UIButton from Interface Builder to the position of Left or RightBarButtonItem on the navigationBar in your storyboard.
Hope it helps.

How to disable Preview screen when using UIImagePickerController Camera

In iOS7 the build-in camera app doesn't go into the preview screen after taking a picture, is there any way that the UIImagePicker can behave like that.
UIImagePickerController * imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.cameraFlashMode = UIImagePickerControllerCameraFlashModeOff;
I know another solution is to create a custom camera using the AVFoundation class, but that is beyond my knowledge at this point and I really like the looks of the default camera.
Update
So after some more research I found out I could create my own shutter button and set it as a camera overlay. Here is what I did
UIButton *shutter = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[shutter addTarget:self action:#selector(shootPicture) forControlEvents:UIControlEventTouchUpInside];
[shutter setTitle:#"S" forState:UIControlStateNormal];
shutter.frame = CGRectMake(50, 50, 60, 60);
UIView *layoutView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
layoutView.opaque = NO;
layoutView.backgroundColor = [UIColor clearColor];
[layoutView addSubview:shutter];
For the 'shootPicture' method
- (void) shootPicture
{
[picker takePicture];
[self imagePickerController:self.camCtl didFinishPickingMediaWithInfo:nil];
}
If I just have the picker call 'takePicture' I will still get the preview, so instead I forced the picker to call didFinishPickingMediaWithInfo right after taking picture. The result is I don't see the preview screen HOWEVER I don't see the picture either. I know I put 'nil' in didFinishPickingMediaWithInfo because I don't know what to put in at this point. I also know it took a picture is in cache somewhere but I really have no idea how to get it.
Any idea would be greatly appreciated =)
This solution works for me:
self.pickerController.allowsEditing = false

How to make a UIActivityIndicatorView in a UIToolbar tappable

I'm using this code to insert an UIActivityIndicatorView to my toolbar
-(void)addActivityIndicatorToToolbar {
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
activityIndicator.userInteractionEnabled = YES;
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite;
[activityIndicator startAnimating];
UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithCustomView:activityIndicator];
barButton.target = self;
barButton.action = #selector(playButtonPressed:);
NSMutableArray *toolbarItemsMutable = [self.toolbar.items mutableCopy];
[toolbarItemsMutable replaceObjectAtIndex:0 withObject:barButton];
self.toolbar.items = toolbarItemsMutable;
}
However, when I tap the UIActivityIndicatorView the action (playButtonPressed) is not performed.
How can I correct this?
It seems more likely that you want a button with an activity indicator inside it. You can do this by creating a button with a custom view as described in this post. Then you can set the action of this button as normal, and you'll probably want to retain a reference to the activity indicator to start and stop it.
I ended up implementing a poor man's solution by adding an extra view on top of the activityIndicatorView with a gestureRecognizer.
This is a quite old question but why don't you directly add a UITapGestureRecognizer instance to your UIActivityIndicatorView instance ? (works fine on iOS 8.2, I didn't test yet on previous versions).

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).

problem with changing view

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.