Disable fullscreen mode in iOS Media Player Controller - iphone

I want to restrict the media player from entering into the fullscreen mode. Is it possible to customize the controllers of the iPhone media player controller? Can we disable the fullscreen
button in the media player controller?

Check the fullscreen property and setFullscreen:animated methods as noted in the docs.
Edit:
I believe I misread your question--apologies.
Not the best solution, but you could override setFullscreen: to simply ignore the request:
- (void)setFullscreen:(BOOL)full {
// Ignore request
}
As far as customizing the controls, you have the option of setting the controlStyle, but all of these have a full screen button, save the "MPMovieControlStyleNone", which give you no controls. You could combine the MPMovieControlStyleNone and overlay your own control bar.
I would probably go for the latter myself, as a disabled button I expect to work as a user would probably be frustrating.
Hope that at least partially earns-away that down vote. :-)
Edit: Adding some more info/code
So here's just something simple you could do. I build a toolbar using IB
and a bit of code for placement and some silly color (this one's a little harsh actually):
NSArray *array = [[NSBundle mainBundle] loadNibNamed:#"bar" owner:self options:nil];
UIToolbar *toolbar;
if ( nil != array ) {
toolbar = array[0];
}
CGSize barSize = CGSizeMake(self.window.frame.size.width, 44);
CGSize winSize = self.window.frame.size;
[toolbar setFrame:CGRectMake(0, winSize.height - barSize.height, winSize.width, barSize.height)];
[toolbar setTranslucent:YES];
[toolbar setBackgroundImage:nil forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
[toolbar setTintColor:[UIColor colorWithRed:138/255 green:187/255 blue:255/227 alpha:0.4]];
[self.window addSubview:toolbar];
Just connect up the buttons, maybe do a clear-color overlay to handle the tap-to-bring-up-controls functionality that's already common in the movie players.

Related

resize toolbar in UINavigationController

I'm adding a series of buttons to a UINavigationBar using:
NSArray *items;
items = [NSArray arrayWithObjects:
fixedSpace,
refreshStopBarButtonItem,
flexibleSpace,
self.backBarButtonItem,
flexibleSpace,
self.forwardBarButtonItem,
flexibleSpace,
self.actionBarButtonItem,
fixedSpace,
nil];
UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0.0f, 0.0f, toolbarWidth, 44.0f)];
toolbar.items = items;
toolbar.tintColor = [[UIColor whiteColor] colorWithAlphaComponent:1.0];
toolbar.autoresizingMask = UIViewAutoresizingFlexibleHeight;
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:toolbar];
All working well.
However when I rotate to landscape mode the toolbar within the uinavigationbar doesn't rotate.
Adding this code (found on SO) causes the toolbar to resize but not the buttons within it, so they are partially cropped at the bottom and no longer lines up with the toolbar background
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
CGRect navigationToolbarFrame = self.navigationController.navigationBar.frame;
CGRect customToolbarFrame = CGRectOffset(navigationToolbarFrame, 0.0, navigationToolbarFrame.size.height);
[UIView animateWithDuration:duration animations:^{
//self.toolbar.frame = customToolbarFrame;
// FAILS!!!
//self.navigationItem.rightBarButtonItem.toolbar.frame = customToolbarFrame;
// FAILS!!!
}];
}
What is the correct way to address the toolbar within the uinavigationbar?
Something like...
self.toolbar.frame = customToolbarFrame;
Or do I have to specify a autoresizemask for the UIBarButtonItems?...
self.backBarButtonItem.autoresizingMask = UIViewAutoresizingFlexibleHeight;
... trying to do so like this fails
Very curious because this code rotates toolbar fine when I include it in my code. No problem rotating the toolbar.
I assume your view controller is responding to shouldAutorotateToInterfaceOrientation? Could you include screen snapshot of what you're seeing?
Are you doing any UIToolbar category/subclass to eliminate its border? (I just subclass with empty (void)drawRect:(CGRect)rect to get rid of border, but I tried both that and the standard UIToolbar and both rotated fine.) Anyway, if you're doing subclass/category of UIToolbar, please include that code?
Also, you could alternatively just use iOS 5's rightBarButtonItems and bypass the toolbar altogether, e.g. self.navigationItem.rightBarButtonItems = items; will then add the array of UIBarButtonItem objects to the navigation bar.
This is a bit of a long shot, but how is your view controller being loaded? Some people try bypassing presentViewControllerAnimated and/or pushViewController and instead simply create a view controller, grab its view, add it as a subview of the previous view controller's view. Unfortunately, this ends up with a disconnect between the view controller hierarchy and the view hierarchy, and according to WWDC 2011 session 102 on view controller containment, this can prevent rotation events from being transmitted correctly. Make sure you're using presentViewControllerAnimated or pushViewController if this isn't your root view controller.
I don't do any of that willAnimateRotationToInterfaceOrientation or subsequent code, just the simple UIToolbar and it works fine during rotation, so I wonder if the problem rests elsewhere.

Making a programmatic iOS UIView fully accessible

I am programmatically building a UINavigationContoller for iOS and am having problems making it fully accessible. In loadView I create the main UIView and set it as NOT accessible:
- (void)loadView
{
CGRect viewRect = [[UIScreen mainScreen] applicationFrame];
UIView *tmp = [[UIView alloc] initWithFrame:viewRect];
[tmp setIsAccessibilityElement:NO];
I then add additional UIViews that contain just background images and also set those as not accessible. All views and controls are added onto the "tmp" UIView created above. Here is a "background" view example:
UIImage* microphone = [UIImage imageNamed:#"microphone.jpg"];
UIView* microphoneView = [[[UIView alloc] initWithFrame: CGRectMake(0,0,viewRect.size.width, microphone.size.height)] autorelease];
[microphoneView setBackgroundColor:[UIColor colorWithPatternImage:microphone]];
[microphoneView setIsAccessibilityElement:NO];
[tmp addSubview:microphoneView];
Finally I add a UIButton, UILabel and UIButtonBarItem. I add these last so they are on the top of the view hierarchy. I add accessibility labels and traits to them. Here is the UIButton:
self.recordImage = [UIImage imageNamed: #"record_button.png"];
self.stopRecordImage = [UIImage imageNamed: #"stop_button.png"];
self.recordButton.accessibilityTraits |= UIAccessibilityTraitStartsMediaSession;
self.recordButton = [[UIButton alloc ] initWithFrame: CGRectMake((viewRect.size.width - recordImage.size.width)/2 , (microphone.size.height + (grayBkg.size.height - recordImage.size.height)/2), recordImage.size.width, recordImage.size.height)];
[self.recordButton setIsAccessibilityElement:YES];
[self.recordButton setAccessibilityLabel: #"toggle recording start"];
[self.recordButton setImage: recordImage forState:UIControlStateNormal];
[self.recordButton addTarget: self action:#selector(processButton:) forControlEvents:UIControlEventTouchUpInside];
[tmp addSubview:recordButton];
finally
....
[self setView:tmp];
[tmp release];
I did call UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil); when I push this view onto the stack.
With voiceover on, when the view is displayed I can swipe and give each of my elements (the UIButtonBarItem, UILabel, and UIButton) focus and I can activate them with double tap. However, VoiceOver speaks no information about the elements. Testing in the simulator with the Accessibility Inspector shows the labels I have set via aControl.accessibilityLabel = #"the label";
This view is used to record audio. If I activate the buttons and record the audio and stop recording, VoiceOver will now speak the labels for the elements when I focus them? Why is VoiceOver not speaking the information when the view first loads? Any clues appreciated!
I am testing on an iPad 2 with iOS 4.3.3.
If you'd like your view to not be accessible, use:
[microphoneView setUserInteractionEnabled:NO];
This view is being used for audio recording. The problem was that I was setting the AVSession Category to AVAudioSessionCategoryRecord in the viewDidLoad method. This was causing VoiceOver not to speak the view information. I modified the code to set the category to AVAudioSessionCategoryRecord only when the record button is pushed. And I set it to AVAudioSessionCategoryPlayAndRecord when recording is finished. Here is the thread that explains it fully: http://lists.apple.com/archives/accessibility-dev/2011/Jul/msg00002.html

UISegmentedControl in Mail app

How do I get a UISegmentedControl that is like the one in the Mail App, so that it is the same colour as UIToolbar buttons (as if both segments were in the selected state).
I want to use the segmented control for exactly the same purpose as Mail.
(on the iPad, so a grey not blue color)
This is code from Apple Sample codes... NavBar and both the images used in the code..
you shoud be able to get exact same view as mail App.
// "Segmented" control to the right
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:
[NSArray arrayWithObjects:
[UIImage imageNamed:#"up.png"],
[UIImage imageNamed:#"down.png"],
nil]];
[segmentedControl addTarget:self action:#selector(segmentAction:) forControlEvents:UIControlEventValueChanged];
segmentedControl.frame = CGRectMake(0, 0, 90, 30);
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentedControl.momentary = YES;
defaultTintColor = [segmentedControl.tintColor retain]; // keep track of this for later
UIBarButtonItem *segmentBarItem = [[UIBarButtonItem alloc] initWithCustomView:segmentedControl];
[segmentedControl release];
self.navigationItem.rightBarButtonItem = segmentBarItem;
[segmentBarItem release];
You seek the tintColor property!
When you use a UISegmentedControl you can change its tint color to any color you can dream up. So, if you added the UISegmentedControl in Interface Builder then you would style it in your - (void)viewWillAppear:(BOOL)animated method as such (assuming you had it hooked up to a #synthesized ivar:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// Set the tintColor to match the navigation bar
self.mySegmentedControl.tintColor = [UIColor colorWithRed:.94 green:.94 blue:.94 alpha:1];
... do whatever else in your viewWillAppear ...
}
Now obviously you will want to play with the red, green, blue, and alpha's that I've put in the sample code above, but you can literally tint the UISegmentedController any color you would like (or make it as transparent as you would like), so it's just a matter of finding the RGBA values that look perfect to you.
Remember that per Apple's docs that the default value of this property is nil (no color). UISegmentedControl uses this property only if the style of the segmented control is UISegmentedControlStyleBar.
Good luck!
I dont know exactly what you mean.. but i believe the "UISegmentedControlStyleBar" as segmentedControlStyle could it be.
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar
You can set this property in the IB too! (It's the property called "style")
The style I'm looking for is undocumented: it is style 4.
It looks like he up/down control here: http://media.mobilemeandering.com/wp-content/uploads/2010/04/ipad-mail-message-2.png
(not my image btw)
It basically makes all segments look selected, it's intended for momentary pushes, and is effectively multiple tool bar buttons pushed up together.
So it can't be set in IB but must be set in code or manually in the nib/xib file, by opening the nib as a text file.
I'm not sure I exactly understand what you're trying to do, but I'll give it a shot.
The solution is not obvious, you need to use a UISearchDisplayController in order to get a matching UISearchBar and UISegmentedControl.
See the TableSearch sample code for an example.

Adding button to left of UISearchBar

I am tearing my hair out on this one. My client wants to add a button to the left of a search bar like the example below:
(source: erik.co.uk)
But I just can't figure out how to do it. Apple don't seem to provide any documented method for adding custom buttons to a UISearchBar, let alone to the left of the search bar.
I've tried hacking around in Interface Builder adding a UIToolbar with a button in it to the left but I cannot find any combination of styles where the two line up properly to give the impression that they are one. There is always what looks like one pixel difference in the vertical alignment as you can see from the picture below:
(source: erik.co.uk)
I've searched around and just can't find the answer, but as we can see from the screenshot it must be possible!
Thank you in advance for your help.
Erik
Use a navigation bar instead of a toolbar. Set the search bar to the navigation bar's title view.
In Interface Builder:
Result:
You can replace the Bookmark image instead, and adjust its offset if necessary.
For example:
[self.searchDisplayController.searchBar setImage:[UIImage imageNamed:#"plus2"] forSearchBarIcon:UISearchBarIconBookmark state:UIControlStateNormal];
[self.searchDisplayController.searchBar setPositionAdjustment:UIOffsetMake(-10, 0) forSearchBarIcon:UISearchBarIconBookmark];
Handle the button event in the delegate method:
- (void)searchBarBookmarkButtonClicked:(UISearchBar *)searchBar
This is how it looks:
The first solution is to use UINavigationBar instead of UIToolbar, as KennyTM noticed. But you may not be satisfied with Navigation bar, like in my case, when I need to use 3 buttons (Navigation bar is allow to use only 2 buttons) - see the left picture. This is how I did it:
Use Toolbar with 3 buttons and Flexible Space Bar Button Item in the place where search bar should be placed.
Put search bar on (not in) the toolbar. To do so in Interface Builder, do not drag & drop the search bar on the toolbar. Instead, put it somewhere nearby and then move it to place using the arrow keys on the keyboard (or by changing X & Y position in Interface Builder).
Search bar left black line under it (see the right picture). To hide it I put one additional view with the height 1px and a white background over it.
It looks a bit dirty for me, so if you have a better solution, let me know.
The easiest solution is to add your SearchBar in TOP of your Toolbar, (not in), I give you the best solution I use in my company eBuildy:
UIBarButtonItem *mySettingsButton = [[UIBarButtonItem alloc] initWithTitle:#"Settings" style:UIBarButtonItemStyleBordered target:self action:#selector(refresh)];
UIBarButtonItem *mySpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *myRefreshButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:#selector(refresh)];
UIToolbar *myTopToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0,0,320,40)];
UISearchBar *mySearchBar = [[UISearchBar alloc]initWithFrame:CGRectMake(70,1,220,40)];
[myTopToolbar setItems:[NSArray arrayWithObjects:mySettingsButton,mySpacer,myRefreshButton, nil] animated:NO];
[self.view addSubview:myTopToolbar];
[self.view addSubview:mySearchBar];
answering an old question here but i was struggling with this one myself recently and found some shortcomings with the other answers for the situation i was trying to address. here's what i did in a subclass of UISearchBar:
first add a UIButton property (here "selectButton"). then override the initWithFrame method and do something similar to the following:
-(id)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame])
{
self.selectButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.selectButton.contentEdgeInsets = (UIEdgeInsets){.left=4,.right=4};
[self.selectButton addTarget:self action:#selector(pressedButton:) forControlEvents:UIControlEventTouchUpInside];
self.selectButton.titleLabel.numberOfLines = 1;
self.selectButton.titleLabel.adjustsFontSizeToFitWidth = YES;
self.selectButton.titleLabel.lineBreakMode = UILineBreakModeClip;
[self addSubview:self.selectButton];
[self.selectButton setFrame:CGRectMake(5, 6, 60, 31)];
}
return self;
}
Now you want to override the layout subviews method to resize the searchbar to the appropriate width, depending on whether or not the cancel button is showing. That should look something like this:
-(void)layoutSubviews
{
[super layoutSubviews];
float cancelButtonWidth = 65.0;
UITextField *searchField = [self.subviews objectAtIndex:1];
if (self.showsCancelButton == YES)
[searchField setFrame:CGRectMake(70, 6, self.frame.size.width - 70 - cancelButtonWidth, 31)];
else
[searchField setFrame:CGRectMake(70, 6, self.frame.size.width - 70, 31)];
}
Note that in the above method I added a constant for the cancelButtonWidth. I tried adding code to get the width from [self cancelButton] but that seems only accessible at runtime and doesn't allow the project to compile. In any case this should be a good start for what you need
If you want a custom button on the right, taking place of the Cancel button, just use this code (valid for iOS 9 and up):
[self.searchBar setShowsCancelButton:YES];
[[UIBarButtonItem appearanceWhenContainedIn:[self.searchBar class], nil] setTitle:#""];
[[UIBarButtonItem appearanceWhenContainedIn:[self.searchBar class], nil] setImage:[UIImage imageNamed:#"search"]];

How do you add more than one UIBarButton on UINavigationItem.rightBarButtonItem (or leftBarButtonItem)?

I have tried this approach/hack:
http://blog.blackwhale.at/2009/06/uibuttons-in-uinavigationbar/
The problem is this leaves a faint seam. I tried setting the background image of the nested toolbar to an image I captured of what it should be. That didn't work. The image was not applied. I have also tried using a nested UINavigationBar and that didn't seem to work.
I have seen this done in several iPhone apps. Does anyone know how?
[EDIT] I want the buttons to look like normal UIBarButtonItems and be able to use system styles like UIBarButtonSystemItemAdd, UIBarButtonSystemItemRefresh. The link I provided does this except you can see a faint seam because it is a UIToolbar nested in the navigationbar..
Please don't mention this breaking the Human Interface Guidelines. (We know).
I appreciate you contributing your hacks... thats the only way to do this!
iOS 5.0 now supports multiple buttons. See the iOS documentation for UINavigationItem. Specifically, the following:
Properties:
#property(nonatomic, copy) NSArray *leftBarButtonItems;
#property(nonatomic, copy) NSArray *rightBarButtonItems;
#property BOOL leftItemsSupplementBackButton;
Methods:
- (void)setLeftBarButtonItems:(NSArray *)items animated:(BOOL)animated;
- (void)setRightBarButtonItems:(NSArray *)items animated:(BOOL)animated;
I posted code to add two buttons to the right of the navigationBar. You can set barStyle = -1 instead of subclassing UIToolbar.
To get rid of the background ('seam') of a UIToolbar, create a subclass of UIToolbar and override the (void)drawRect:(CGRect)rect method. Leave that blank and your UIToolbar will no longer have a background.
Just used this in my own project and worked great. Found this in the comments of: http://osmorphis.blogspot.com/2009/05/multiple-buttons-on-navigation-bar.html
UIView *parentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, myWidth, myHeight)];
// make UIView customView1... (UILabel, UIButton, etc.) with desired frame and settings
[parentView addSubview:customView1];
[customView1 release];
// make UIView customView2... (UILabel, UIButton, etc.) with desired frame and settings
[parentView addSubview:customView2];
[customView2 release];
UIBarButtonItem *customBarButtomItem = [[UIBarButtonItem alloc] initWithCustomView:parentView];
[parentView release];
self.navigationItem.rightBarButtonItem = customBarButtomItem;
[customBarButtomItem release];
see uicatalogue example available at apple's site for free...they used uisegmented control to show three buttons in place of right bar button on navigaion bar...
I can't comment but in addition to #iworkinprogress I had to set the UIToolbar background color to clear:
[toolbar setBackgroundColor:[UIColor clearColor]];
This was also found in the comments of http://osmorphis.blogspot.com/2009/05/multiple-buttons-on-navigation-bar.html.
In iOS 4.x the clearColor seems to have no effect on the UIToolbar, whereas overriding its drawRect: did.
I came up with a helper function I'm using all over my project. Basically it checks if there is already a button on the bar and either add the new one or merge it with existing buttons. So you can call the function just once or multiple times:
+ (void)AddButtonToBar:(UIViewController *)controller withImage:(NSString *)imageName withAction:(SEL)action withFrame:(CGRect) frame{
UIButton *newButton =[[UIButton alloc] init];
[newButton setBackgroundImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
newButton.frame = frame;
[newButton addTarget:controller action:action forControlEvents:UIControlEventTouchUpInside];
if ([[controller.navigationItem rightBarButtonItems] count] == 0)
[controller.navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithCustomView:newButton]];
else {
NSMutableArray *existingButtons = [[NSMutableArray alloc] initWithArray:[controller.navigationItem rightBarButtonItems]];
[existingButtons addObject:[[UIBarButtonItem alloc] initWithCustomView:newButton]];
[controller.navigationItem setRightBarButtonItems:(NSArray *)existingButtons];
}
}
Call it from the view controller:
[Helper AddButtonToBar:self withImage:#"imageName.png" withAction:#selector(myAction) withFrame:CGRectMake(0, 0, 24, 24)];