When using the MPMoviePlayerController I want to override fullscreen button tap or to hide it so I can add a custom button.
The mission is to really change the MPMoviePlayerController frame and other subviews frame.
Any ideas? Or I must use different video player to accomplish that?
First of all remove gestures of your MPMoviePlayerController. Then add your custom gestures or Button or other control.
self.player.view.gestureRecognizers = nil;
//Add your custom gestures or Button or other control
I recently was solving similar issue. My client was insisting to disable Previous and Next buttons although I was strongly recommend to do that because it's quite tricky and not guaranteed to work in next iOS version. So here I publish my solution as an very unwanted option)
-(void) disableNextPrevButtons:(UIView *) view :(int) level {
Class cl = NSClassFromString(#"MPKnockoutButton");
for (UIView * v in view.subviews) {
NSLog(#"[%d] scanning view of class %# tag: %ld", level, NSStringFromClass(v.class), (long)v.tag);
if ([v isKindOfClass:cl]) {
for (UIView * v2 in v.subviews)
if ([v2 isKindOfClass:[UIImageView class]]) {
v.alpha = 0.0;
v.userInteractionEnabled = NO;
if (!buttonsDiscovered) {
buttonsDiscovered = YES;
UIButton * b = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, v.superview.frame.size.height, v.superview.frame.size.height)];
if (MLGSystemVersion() > 7.9)
b.alpha = 0.5;
b.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin |
UIViewAutoresizingFlexibleRightMargin |
UIViewAutoresizingFlexibleTopMargin |
UIViewAutoresizingFlexibleBottomMargin);
[b setImage:[UIImage imageNamed:#"btnMPPause.png"] forState:UIControlStateNormal];
[b setImage:[UIImage imageNamed:#"btnMPPlay.png"] forState:UIControlStateSelected];
b.selected = YES;
[b addTarget:self action:#selector(btnPlayPauseDidPress:) forControlEvents:UIControlEventTouchUpInside];
b.center = CGPointMake(v.superview.frame.size.width / 2, v.center.y);
[v.superview addSubview:b];
self.btnPlayPause = b;
}
break;
}
} else
[self disableNextPrevButtons:v :level +1];
}
}
The method is recursevely scans and finds the desired controls and do some bad things to them
Related
I have a text field that I want to have a keyboard like this when user start typing:
please also see this video: https://youtu.be/iU_jocny3N0
As you can see in this video there is a "ABC" key that helps user to switch from number pad to text. and also when press "123" in text the keyboard switchs from text to number pad. I am wondering how they do this?
The only solution that I found was adding a subview to keyboard like what described here:
Adding Done Button to Only Number Pad Keyboard on iPhone
but this way may not work when user uses custom keyboards. and also do not works for switching from text to number pad.
Or as another solution I know accessoryInputView but this is not like the video. It adds a toolbar above the keyboard.
Does someone knows the solutions that is used in this video?
I have added comma button to the keyboard,
Keyboard is also a simple UIView Which contains Controls
NOTE: This is old code was working in my old project Not tested in new projects
- (void) keyboardWillShow:(NSNotification *)note {
// create custom button
dispatch_async(dispatch_get_main_queue(), ^{
// Some code
UITextField *txt = (UITextField *)[self.view findFirstResponder];
if (txt.keyboardType == UIKeyboardTypeDecimalPad) {
UIButton * btnComma = [UIButton buttonWithType:UIButtonTypeCustom];
[btnComma setTag:15000];
UIView* keyboard = [self findKeyboard];
// btnComma.frame = CGRectMake(0, 162, 126, 54);
btnComma.frame = [self findKeySizeForView:keyboard];
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"8.0")) {
[btnComma setTitleEdgeInsets:UIEdgeInsetsMake(0, 0, 20, 0)];
}
[btnComma setBackgroundColor:[UIColor colorWithHexString:#"CBD0D6"]];
btnComma.adjustsImageWhenHighlighted = NO;
[btnComma setTitle:#"." forState:UIControlStateNormal];
[btnComma setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btnComma.titleLabel setFont:[UIFont systemFontOfSize:35.0f]];
[btnComma addTarget:self action:#selector(commaBtnTapped) forControlEvents:UIControlEventTouchUpInside];
[keyboard addSubview:btnComma];
btnComma = nil;
}
});
}
- (UIView *) viewWithPrefix:(NSString *)prefix inView:(UIView *)view {
for (UIView *subview in view.subviews) {
if ([[subview description] hasPrefix:prefix]) {
return subview;
}
}
return nil;
}
This method for finding keyboard from UIWindow
- (UIView *) findKeyboard {
for (UIWindow* window in [UIApplication sharedApplication].windows) {
UIView *inputSetContainer = [self viewWithPrefix:#"<UIInputSetContainerView" inView:window];
if (inputSetContainer) {
UIView *inputSetHost = [self viewWithPrefix:#"<UIInputSetHostView" inView:inputSetContainer];
if (inputSetHost) {
UIView *kbinputbackdrop = [self viewWithPrefix:#"<_UIKBCompatInput" inView:inputSetHost];
if (kbinputbackdrop) {
UIView *theKeyboard = [self viewWithPrefix:#"<UIKeyboard" inView:kbinputbackdrop];
return theKeyboard;
}
}
}
}
return nil;
}
and For finding size of bottom right button
- (CGRect ) findKeySizeForView:(UIView *)view {
if (view != nil) {
UIView *uiKeyboardImpl = [self viewWithPrefix:#"<UIKeyboardImpl" inView:view];
if (uiKeyboardImpl != nil) {
UIView *uiKeyboardLayoutStar = [self viewWithPrefix:#"<UIKeyboardLayoutStar" inView:uiKeyboardImpl];
if (uiKeyboardLayoutStar != nil) {
UIView *uiKBKeyplaneView = [self viewWithPrefix:#"<UIKBKeyplaneView" inView:uiKeyboardLayoutStar];
if (uiKBKeyplaneView != nil) {
for (view in [uiKBKeyplaneView subviews]) {
CGPoint pointOrigin = view.layer.frame.origin;
if (pointOrigin.x <= 0 && pointOrigin.y == uiKBKeyplaneView.frame.size.height - view.frame.size.height && [[view description] hasPrefix:#"<UIKBKeyView"])
return view.layer.frame;
}
}
}
}
}
return CGRectZero;
}
I want to do an animation that zooms in from a calendar, specifically with the origin and frame size being that of the button that represent's today's date. Here is the code for determining the todayButton inside CalendarMonthView.m:
NSDate *date = (weekdayOffset > 0) ? [_monthStartDate dateByAddingTimeInterval:-1 * weekdayOffset * D_DAY] : _monthStartDate;
BOOL bEnabled = (weekdayOffset == 0);
CGRect buttonFrame = CGRectMake (0, 0, 81, 61);
int idx = -1 * weekdayOffset;
for (int y = 0; y < 6; y++) {
buttonFrame.origin.x = 0;
for (int x = 0; x < 7; x++) {
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.tag = idx++;
[button setFrame:buttonFrame];
[button setBackgroundImage:[UIImage imageNamed:#"calendarFlyout_dayContainer_today.png"] forState:UIControlStateSelected];
[button setBackgroundImage:[UIImage imageNamed:#"calendarFlyout_selected.png"] forState:UIControlStateHighlighted];
button.titleLabel.font = [UIFont fontWithName:#"TitilliumWeb-Regular" size:18.0];
button.titleLabel.textAlignment = NSTextAlignmentCenter;
// TODO: optimize performance
int dayOfMonth = (int)[_calendar component:NSCalendarUnitDay fromDate:date];
if (dayOfMonth < prevDayOfMonth) {
bEnabled = !bEnabled;
}
prevDayOfMonth = dayOfMonth;
[button setTitle:[NSString stringWithFormat:#"%d", dayOfMonth] forState:UIControlStateNormal];
[button setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal];
[button setTitleColor:[UIColor lightGrayColor] forState:UIControlStateDisabled];
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];
[button setBackgroundImage:[UIImage imageNamed:((bEnabled) ? #"calendarFlyout_dayContainer_insideMonth.png"
: #"calendarFlyout_dayContainer_outsideMonth.png")]
forState:UIControlStateNormal];
// button.enabled = bEnabled;
button.selected = [date isToday];
if (button.selected == NO) {
button.highlighted = (_currentDayDate) ? [date isEqualToDateIgnoringTime:_currentDayDate] : NO;
} else {
// Set buttonHolder to today
}
[button addTarget:self action:#selector (dayButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[_dayButtonsHolderView addSubview:button];
buttonFrame.origin.x += buttonFrame.size.width;
date = [date dateByAddingTimeInterval:D_DAY];
}
buttonFrame.origin.y += buttonFrame.size.height;
}
- (IBAction)dayButtonTapped:(id)sender
{
if (_delegate) {
UIButton *button = (UIButton *)sender;
NSDate *selectedDate = [_monthStartDate dateByAddingDays:button.tag];
[_delegate performSelector:#selector (calendarMonthView:dateSelected:) withObject:self withObject:selectedDate];
}
}
I want to get the frame of button and use it in this animation used in CalendarFlyoutView.m.
I'm new to iOS programming and I read up on some delegate information and passing information through segues, but it doesn't seem to help me here.
Any help would be greatly appreciated.
Use the transform feature.
// animate in year calendar
_yearCalendarView.hidden = NO;
self.curMonthView.monthLabel.hidden = YES;
CalendarMonthView *monthView = [CalendarMonthView new];
monthView.delegate = self;
CGRect buttonFrame = _currentDayButtonFrame;
_yearCalendarView.frame = CGRectMake(buttonFrame.origin.x, buttonFrame.origin.y + buttonFrame.size.height, buttonFrame.size.width, buttonFrame.size.height);
NSLog(#"_yearCalendarView frame: %#", NSStringFromCGRect(_yearCalendarView.frame));
_yearCalendarView.transform = CGAffineTransformMakeScale(0.01, 0.01);
[UIView animateWithDuration:kAnimation_ExpandCalendarDuration delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
_yearCalendarView.transform = CGAffineTransformIdentity;
_yearCalendarView.frame = CGRectMake(_monthSwiperScrollView.frame.origin.x, _monthBarImageView.frame.size.height + 20, _monthSwiperScrollView.frame.size.width + 2, _yearFlyoutHeight);
} completion:^(BOOL finished) {
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector (yearCalendarAnimationDidStop:finished:context:)];
}];
If you are making a segue from the CalendarMonthView to the CalendarFlyoutView then you can just add this method to the CalendarMonthView.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
CalendarFlyoutView * view = segue.destinationViewController;
view.buttonFrame = button.frame;
}
and in your CalendarFlyoutView.h
#interface CalendarFlyoutView : UIViewController
#property CGRect buttonFrame;
#end
A couple of questions that need to be answered to best help you:
1) Are CalendarMonthView and CalendarFlyoutView UIView or UIViewController? You say view controller, but the class name says otherwise.
2) What is happening in the method 'dayButtonTapped'? Are you performing a segue there? Are you somehow creating or loading an instance of CalendarFlyoutView?
3) If you are not using a segue, are you somehow creating and add a child view controller for CalendarFlyoutView to CalendarMonthView?
4) What is the desired transition (your animation)? Does the CalendarFlyoutView start at the same size as the button, then fill the whole screen?
5) Is there a specific reason that you are setting the button's frame instead of constraining it in the correct place?
Once we know a little more about these questions we should be able to provide some more concrete suggestions.
It's still not very clear where the actual animation code is being run. In your question, you state "I want to get the frame of button and use it in this animation used in CalendarFlyoutView.m." which seems to imply the animation code is in CalendarFlyoutView, which seems like an odd place for it.
There are a few things I could recommend, given my incomplete understanding of the whole of the code:
1) Move the animation code to the dayButtonTapped method, where you already have a reference to the button, and therefore it's frame. It also seems like a more logical place for it.
2) Where ever you are instantiating the CalendarFlyoutView (not shown in the code you posted), assign the button frame there.
3) If there is only a single instance of CalendarFlyoutView and you have a reference to it in CalendarMonthView, you could assign a property of the flyout view that is the frame of the button you already have a reference to in the dayButtonTapped method.
I have to add though, that these are just work arounds to what seems like a structural issue. Is this a reusable control you are trying to write? Why did you decide to not use the storyboard or view controllers? Why are you using frames and absolute sizes and positions at all instead of letting auto layout do it's job (you will bang your head against the wall for hours trying to tweak everything to run correctly in all orientations and all possible device screen sizes).
Hi and thanks in advance for you patience and help :)
Here is what I am doing:
- I create programmatically multiple buttons that call the same function
And what I want to accomplish:
- after a button is pressed, I want the common function to run and all the buttons to be disabled so that the function won't be called again during execution of the firs call. after the first call is ended I want to reenable the buttons.
Here is how I create the buttons:
#interface ViewController ()
{
UIButton *button;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
int tagForTheButton = 0;
int yPossition = 0;
int xPossition = 0;
for (int numberOfTheColomn = 0; numberOfTheColomn < 6; numberOfTheColomn++) {
button = [UIButton buttonWithType:UIButtonTypeCustom];
button.adjustsImageWhenHighlighted = NO;
button.frame = CGRectMake(xPossition, yPossition, 64, 64);
button.tag = tagForTheButton;
[button setTitle:title forState:UIControlStateNormal];
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.scroll addSubview:button];
yPossition=yPossition+100;
tagForTheButton++;
}
}
-(void)buttonPressed:(id)sender{
//This is my attempt to disable the buttons
//previous mistake used 2578
for (int numberForIncrease; numberForIncrease<6; numberForIncrease++) {
if (button.tag == numberForIncrease) {
UIButton *btn = (UIButton*)[self.scroll viewWithTag:numberForIncrease];
btn.enabled=NO;
[btn setUserInteractionEnabled:NO];
}
}
}
You must be disabling it incorrectly. The docs for UIButton.enabled state:
If the enabled state is NO, the control ignores touch events and
subclasses may draw differently.
Check that DisableButton is being called by adding an NSLog() call, & do away with the DisableButton method altogether:
dispatch_sync(dispatch_get_main_queue(), ^{
self.view.userInteractionEnabled = NO;
_btn_sync_outlet.enabled = NO;
_btn_sync_outlet.userInteractionEnabled = NO;
});
This might helps you :)
I don't understand why you need to loop from 0 to 2577 for disabling a button which you already have an iVar pointing to..?
why don't you just switch off userInteraction to your entire view (or if that is not possible to a containerView which holds all the buttons)?
[self.view setUserInteractionEnabled: NO ];
or, failing that why not just haver an iVar there?
{
BOOL _ignoreButtons;
}
-(void)buttonPressed:(id)sender{
if (!_ignoreButtons){
_ignoreButtons = YES;
//do your time consuming job, possibly on bg thread
//on completion..
_ignoreButtons = NO;
}
}
Hey so I have created two buttons that when pressed transition the current scene to either the next scene or the main menu and they work but neither button disappears after it has been pressed. They both carry over onto the next scene which I don't want. I've tried hiding the buttons and removing them from the superView but neither worked. Heres what the code looks like for what happens when it is pressed.
-(IBAction)buttonPressed:(UIButton *)sender
{
if ([sender isEqual:self.continueButton]) {
SKTransition* reveal = [SKTransition doorsCloseVerticalWithDuration:0.5];
SKScene* transition2Scene = [[Transition2Scene alloc] initWithSize:self.size];
[self.view presentScene:transition2Scene transition: reveal];
[self.continueButton removeFromSuperview];
self.continueButton.hidden = YES;
self.continueButton.enabled = NO;
}
else {
SKTransition* doors = [SKTransition doorsCloseVerticalWithDuration:0.5];
SKScene* spriteMyScene = [[SpriteMyScene alloc] initWithSize:self.size];
[self.view presentScene:spriteMyScene transition: doors];
self.menuButton.hidden = YES;
self.menuButton.enabled = NO;
[self.menuButton removeFromSuperview];
}
}
And heres what the coding of the buttons themselves looks like.
self.continueButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.continueButton.frame = CGRectMake(self.frame.size.width/3, self.frame.size.height * 0.5, 120, 70);
[self.continueButton setTitle:#"Continue" forState:UIControlStateNormal];
[self.continueButton addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.continueButton];
self.menuButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.menuButton.frame = CGRectMake(self.frame.size.width/3, self.frame.size.height * 0.6, 120, 70);
[self.menuButton setTitle:#"Main Menu" forState:UIControlStateNormal];
[self.menuButton addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.menuButton];
I've looked around for answers and tried some things but they didn't work cause the issue I'm having isn't quite the same so any help would be greatly appreciated thanks!
The SKScene and its contents are remove from the view when transitioning to a new scene. Views, such as your buttons, are not removed. You will need to manually remove them. Here's an example...
- (IBAction) buttonPressed:(UIButton *)sender
{
[self.continueButton removeFromSuperview];
[self.menuButton removeFromSuperview];
// Find and remove all UIButtons in your view
for (UIView *view in self.view.subviews) {
if ([view isKindOfClass:[UIButton class]]) {
NSLog(#"%#", view);
[view removeFromSuperview];
}
}
// Verify that the UIButtons were removed
for (UIView *view in self.view.subviews) {
if ([view isKindOfClass:[UIButton class]]) {
NSLog(#"this shouldn't happen: %#", view);
}
}
// The rest of your code
Alternatively, you can create buttons using SKSpriteNode and add them to your scene. Here's an example...
Setting up buttons in SKScene
I created five buttons using for loop, it works well. Whenever i click restart button duplicate buttons created
-(void)buttonCreate {
for( int i = 0; i < 5; i++ )
{
oneBtn1 = [UIButton buttonWithType:UIButtonTypeCustom];
oneBtn1.frame = CGRectMake(316,i*-5+474,51,50);
[oneBtn1 setTag:i];
[oneBtn1 addTarget:self action:#selector(oneButton:) forControlEvents:UIControlEventTouchUpInside];
[oneBtn1 setImage:[UIImage imageNamed:#"1c.png"] forState:UIControlStateNormal];
[self.view addSubview:oneBtn1];
}
}
Restart button function:
-(void)restart {
[self buttonCreate];
}
I tried this one but it will remove only one button out of 5.
if(oneBtn1 != NULL) {
[oneBtn1 removeFromSuperview];
oneBtn1 = nil;
}
Problem is: How to remove duplicate buttons?
Create an array(NSMutableArray *buttonHolderArray) to hold outlets for all five buttons.
[buttonHolderArray addObject:oneBtn1];
Then you can remove/update the buttons as and when you need.
And once you dont want any button, empty the array itself. On top of this, if you wish to clear the view then simply call removeFromSuperView for all the buttons
I tried this one but it will remove only one button out of 5.
if(oneBtn1 != NULL) {
[oneBtn1 removeFromSuperview];
oneBtn1 = nil;
}
You are removing only one button, if you want to remove all then use
for ( UIButton *button in buttonHolderArray){
button removeFromSuperView];
}
You can remove by checking if the button is already created.
-(void)buttonCreate {
int tag_start = 500;
for( int i = 0; i < 5; i++ )
{
UIView * prevbtn = [self.view viewWithTag:tag_start + i];
if(prevbtn) {
[prevbtn removeFromSuperview];
}
oneBtn1 = [UIButton buttonWithType:UIButtonTypeCustom];
oneBtn1.frame = CGRectMake(316,i*-5+474,51,50);
[oneBtn1 setTag:tag_start + i];
[oneBtn1 addTarget:self action:#selector(oneButton:) forControlEvents:UIControlEventTouchUpInside];
[oneBtn1 setImage:[UIImage imageNamed:#"1c.png"] forState:UIControlStateNormal];
[self.view addSubview:oneBtn1];
}
}
use this before calling again restart method
for (UIButton *btn in self.view.subviews ) {
[btn removeFromSuperview];
}
Before the restart button clicked you can remove all the buttons from you view calling the method removeChildViewsWithKindOfClass
-(void)restart {
[self.view removeChildViewsWithKindOfClass:[UIButton class]];
[self buttonCreate];
}
-(void)removeChildViewsWithKindOfClass:(Class)classToRemove{
if (classToRemove==nil) return;
for (UIView *v in [self subviews]) {
if ([v isKindOfClass:classToRemove]) {
[v removeFromSuperview];
}
}
}
If you want to remove a specific button you can use the property tag that you have to set beforehand when you create your button and it allows you removing the button with a specific tag.