I'm curious to know is there a way to edit what happens at a app startup to hide buttons? I can hide them when the app is running but I want some buttons hidden when the app starts up and displayed later on after me touching one of my displayed buttons, is there a way to do this?
In code
UIView has a hidden property. You can toggle it to hide/show as you want in code, for example:
myView.hidden = YES; // YES/NO
You'll want to do this anywhere after -viewDidLoad
Interface Builder
In the inspector, once you've selected the view you want to hide, you should see something like this (look in the View > Drawing options - at the bottom).
It's the hidden property you want to check here... You'll want to make an outlet to your code so you can unhide this later on...
You could initially set your buttons hidden via the Attribute Inspector.
There's a check box down there View -> Drawing -> Hidden to hide the button.
Then you coud to set your buttons visible in the touch action of another visible button like following:
#import "HBOSViewController.h"
#interface HBOSViewController ()
// your buttons outlets here
#property (weak, nonatomic) IBOutlet UIButton *topButton1;
#property (weak, nonatomic) IBOutlet UIButton *topButton;
#end
#implementation HBOSViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
// The action of the visible button to make your hidden button visible.
- (IBAction)showButton:(id)sender {
if (self.topButton) {
self.topButton.hidden=NO;
}
if (self.topButton1) {
self.topButton1.hidden=NO;
}
}
#end
I assume you mean on a view which you created using a XIB (Interface Builder) file. If that's the case, simply set the hidden flag on any buttons you want to be initially hidden.
In -viewDidLoad just add something like yourButton.hidden = YES;
Related
I know there are some questions about how to show a toolbar above keyboard.
I read some of them. But, I could not make the toolbar which have TextView like message app. I want to make a toolbar which is showed when button tapped.
I also use IB to create a toolbar because I need some adjustment to appearance.
The code now I make is below.
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UIToolbar *ibToolbar;
// this text view is subview of ibToolbar
#property (weak, nonatomic) IBOutlet UITextView *barTextView;
#end
- (void)viewDidLoad {
[super viewDidLoad];
[self.ibToolbar removeFromSuperview];
self.barTextView.inputAccessoryView = self.ibToolbar;
}
- (IBAction)buttonPushed:(id)sender {
[self.barTextView becomeFirstResponder];
}
When I tap the button, I want to look at toolbar above keyboard to put text on textView.
But, nothing happened when I push the button.
I think that why this code does not work, also because the viewController's view does not parent view of the toolbar,so [self.barTextView becomeFirstResponder] can not be effective.
I think that something else which I did is needed to work the things.
If anyone know do the things work, please tell me.
I have custom UIButton which programmatically interacts (triggers) with ViewController methods via protocol. But the behaviour of the button has to be dependent on the ViewController placed on. I do this to minimise amount of code in ViewControllers itself, as the button has to remain the same and bear the same functions (navigation).
Is there any way in UIButton's custom class to get the ViewController it is placed on?
I'd follow #rmaddy advice in a specific way, borrowing from the SDK's style
// MyCutomButton.h
#protocol MyCustomButtonDatasource;
#interface MyCustomButton : UIButton
#property(weak,nonatomic) IBOutlet id<MyCustomButtonDatasource>datasource;
// etc
#end
#protocol MyCustomButtonDatasource <NSObject>
#optional
- (NSString *)howShouldIBehave:(MyCustomButton *)button;
#end
Now the button can have it's datasource set in IB. View controllers that include it will need a little additional code (sorry, it's unavoidable in a good design). They will declare themselves as implementing MyCustomButtonDatasource.
When MyCustomButton needs to behave conditionally based on where it's placed, it can ask its datasource...
// MyCustomButton.m
NSString *string = #"defaultBehavior"; // per #RichardTopchiy's suggestion
if ([self.datasource respondsToSelector:#selector(howShouldIBehave:)])
string = [self.datasource howShouldIBehave:self];
// string is just made-up here, have it answer something simple (int, BOOL)
// that lets the button proceed with the right behavior. Don't ask for
// anything that relies on specific knowledge of how MyCustomButton
// is implemented
EDIT - To create the relationship, if you've decorated the property as an IBOutlet (as shown above), you should be able to setup the relationship in IB. Declare your view controller as implementing <MyCustomButtonDatasource>. Select your custom button, then the connections inspector, then drag to your view controller.
Alternatively, make the button itself an IBOutlet property in the view controller and, in viewDidLoad, do:
self.customButton.datasource = self;
The last way to do it is give your button a tag, say, 128, then:
MyCustomButton *customButton = (MyCustomButton *)[self.view viewWithTag:128];
self.customButton.datasource = self;
I have four buttons on a single view. Each button has a different IBaction. Once one is pressed I would like to lock out all buttons from being pressed again until the action is completed. I have tried to give each one a property in the .h and then under each IBAction in the .m, I have set each of the four buttons like this btnHelp.enabled =NO;,., etc and then at the end before the final } I have reenabled them all. This hasn't worked. I am a new to objective-C and xcode and greatly appreciate any help.
This is IOS. The .h code is :
#property (strong, nonatomic) IBOutlet UIButton *btnHelp;
#property (strong, nonatomic) IBOutlet UIButton *btnSpin;
#property (strong, nonatomic) IBOutlet UIButton *btnScore;
#property (strong, nonatomic) IBOutlet UIButton *btnBet;
- (IBAction)slotHelp:(id)sender;
- (IBAction)slotSpin:(id)sender;
- (IBAction)slotBet:(id)sender;
- (IBAction)slotScore:(id)sender;
The .m is :
#synthesize btnHelp, btnScore, btnSpin, btnBet;
- (void)viewDidLoad
{
[super viewDidLoad];
btnHelp.enabled = NO;
btnBet.enabled = NO;
btnScore.enabled = NO;
btnSpin.enabled = NO;
// do some introductory setup and give some spoken instructions
// Load plist data into array, etc
// Then reenable buttons
btnHelp.enabled=YES;
btnBet.enabled=YES;
btnScore.enabled=YES;
btnSpin.enabled=YES;
}
-(IBAction)slotHelp {
// Disable buttons while we complete action
btnHelp.enabled = NO;
btnBet.enabled = NO;
btnScore.enabled = NO;
btnSpin.enabled = NO;
// stuff to do
// Reenable buttons after action event completed
btnHelp.enabled=YES;
btnBet.enabled=YES;
btnScore.enabled=YES;
btnSpin.enabled=YES;
}
There are three other action events for the other three buttons.
What I was trying to do is prevent accidental button presses during and action execution. I was hoping to have no chance of simultaneous button presses by accident. I am trying to make an app for use by physically challenged individuals who may accidentally press more than one button. I hope this helps explain a bit of why I want to block multiple presses even the same button.
Thanks for your interest and help.
As one of the most simple solution you may add a bool flag variable to your view class and add a check in you IBaction methods. Something like this
- (void)viewDidLoad
{
[super viewDidLoad];
lock = true;
// do some introductory setup and give some spoken instructions
// Load plist data into array, etc
// Then reenable buttons
lock = false;
}
-(IBAction)slotHelp {
if(!lock) {
lock = true;
//do what you need
lock = false;
}
and do the same check for all the other IBActions
As alternative way, you can globally block-unblock events with methods posted below, instead of blocking each button separately:
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
and
[[UIApplication sharedApplication] endIgnoringInteractionEvents];
But be careful. Wrong strategy of using of these methods can block your application.
I have a view that contains a UIScrollView. The UIScrollView contains an UIImageView (only one for now but there will be more latter). I want to be able to drag the UIImageView out of the UIScrollView and into the superview.
I have reviewed every similar question and example I can find online and still cant get my head around how this works.
At first I couldn't get touches to register all whithin the scrollview. After a lot of searching I have found a way to get touchesbegan to register as follows:
First I created a new view based project and in the auto-created "ViewController.h"
I created an IBOutlet named slider.
Then in the auto-created "ViewController.m" I created the UIScrollview.
In IB I added a UIScrollView to the storyboard then connected it to the "slider" IBOutlet.
Next I added class file to the projects. This new class is a subclass os UIImageView. I named this class "DragableImage" In the
Then in IB I dropped an image into the UIScrollview clicked on it and changed the class to "DragableImage"
In the DragableImage.m I voided touches began and simply told it to become hidden if clicked.
This works and the touch registers and makes the image disappear but how do I now add the new image to the main view and have it follow my finger?
This is what I have in the way of code:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController {
IBOutlet UIScrollView *slider;
}
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[slider setScrollEnabled:YES];
[slider setContentSize:CGSizeMake(306, 1560)];
[slider setShowsVerticalScrollIndicator:NO];
slider.canCancelContentTouches = NO;
slider.delaysContentTouches = NO;
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
#end
DragableImage.h
#import <UIKit/UIKit.h>
#interface DragableImage : UIImageView
#end
DragableImage.m
#implementation DragableImage
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
self.hidden = YES;
}
#end
How to make this work?
There is one obvious problem that can arise here. Namely, how to tell the difference between dragging to scroll and dragging an image. The way I would handle this is to setup a tap and hold gesture recognizer (http://developer.apple.com/library/ios/#documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/GestureRecognizers/GestureRecognizers.html).
Once you detect a hold you could set it up so that further touches/gestures get routed to you drag and drop code. You can find a nice tutorial for that here:
http://www.ancientprogramming.com/2012/04/05/drag-and-drop-between-multiple-uiviews-in-ios/
I am new to IOS, Xcode and MVC. I am on a steep learning curve and am failing with what I assume is a most basic task.
I have a tabbed application with two tabs. Both tab views communicate with a web service and I want to add an image to each tab view, changing the image to indicate the connection state.
So, I created a third .xib file with a controller class (IconViewController). I am hoping to add and remove an instance of this icon view in each of the tab views.
Here is the pseudo code for my icon view:
#interface IconViewController : UIViewController
{
UIImageView *_icon;
}
#property (nonatomic) IBOutlet UIImageView *icon;
- (void)setForBusy;
- (void)setForOk;
- (void)setForFail;
And implementation:
#implementation IconViewController
#synthesize icon = _icon;
-(void)setForBusy
{
// Set Busy Icon Image
}
-(void)setForOk
{
// Set Ok Icon Image
}
-(void)setForFail
{
// Set Fail Icon Image
}
The icon IBOutlet is connected to an UIImageView on the accompanying xib file.
Here is one of the root tab controllers:
#import "IconViewController.h"
#interface TaboneViewController : UIViewController
{
IconViewController *_iconViewController;
}
#property (nonatomic) IBOutlet IconViewController *iconViewController;
and implementation:
#synthesize iconViewController = _iconViewController;
- (void)viewDidLoad
{
[super viewDidLoad];
self.iconViewController = [[IconViewController alloc]
initWithNibName:#"iconViewController"
bundle:nil];
[self.view addSubview:self.iconViewController.view];
}
In the tabView xib Interface Builder I added an Object and made it a class type IconViewController. I connected the Icon View Controller Object->Reference Outlet to the File Owner->iconViewController Outlet.
Running the project I get the error:
loaded the "iconViewController" nib but the view outlet was not set.
I have experimented with other connections but with no luck. It seems to me that my first connection should work but it doesn't.
Any idea what I am misunderstanding? Is the principle good (loading an instance of third view into two root views)? If so, what outlet needs connecting?
Many thanks, Polly
I see your issue. You want to have common stage of image for both tab. I think it is better to implement subclass of UIView (or UIImageView) and implement all methods like set (void)setForBusy and etc. The stage of image you should receive from parent ViewController, something like UINavigationView controller (if you have it). Otherwise you should save stage somewhere else. My personal opinion it is too expensive to create new controller just for your purpose.
Hope it helps.