tvOS buttons created in code cannot be focused - focus

Creating my first yellow world style tvOS app and cannot get my first button to work...
No matter what I cannot get this button to be focused. I've tried the same thing in swift with the same result.
- (void)viewDidLoad {
[super viewDidLoad];
startSlideshowButton = [[UIButton alloc]initWithFrame:CGRectMake(100, 100, 300, 50)];
[startButton setTitle:#"Start" forState:UIControlStateNormal];
[startButton addTarget:self action:#selector(startPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:startButton];
[self setNeedsFocusUpdate];
}
-(UIView*)preferredFocusedView{
return startButton;
}

Was using the wrong controlEvent
correct:
[startButton addTarget:self action:#selector(startPressed:) forControlEvents:UIControlEventPrimaryActionTriggered];

Related

How do I properly add a button to my scene using only code?

Working off of other Stack Overflow answers, I have managed to come up with the code below:
(in my homescreen.m file)
UIButton *GCButton;
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
//add button
[self addGameCenterButton];
}
return self;
}
-(void)addGameCenterButton
{
GCButton = [[UIButton alloc]initWithFrame:CGRectMake(50, 20, 30, 30)];
[GCButton setBackgroundColor:[UIColor orangeColor]];
[GCButton setTitle: #"My Button" forState:UIControlStateNormal];
[GCButton setTitleColor: [UIColor blueColor] forState:UIControlStateNormal];
[GCButton.layer setBorderWidth:1.0f];
[GCButton.layer setBorderColor:[UIColor blueColor].CGColor];
//adding action programatically
[GCButton addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:GCButton];
}
-(void)buttonClicked:(UIButton*)sender
{
NSLog(#"you clicked on button %ld", (long)sender.tag);
}
As of right now, I see nothing on my screen. Is there anything else I need to add in my .m or .h files to make the button work?
From the comments of your question, I'm assuming you are using SpriteKit. In a GameScene, unfortunately, you cannot use UIButtons normally.
To create buttons for your scene, please check the answers in the link below:
Setting up buttons in SKScene

Why the sender not called when I click the image of the button in Objective-C?

I am new to IOS and Objective-C , and I try to set Image for a UIButton.
Wen I click the button , the button will change image1. If I click the button one again , it will change to image2
First, I set the image in Viewdidload like the following code.
#interface AITPreviewViewController ()
{
VLCMediaPlayer *mediaPlayer ;
BOOL recording ;
BOOL recordMode;
}
- (void)viewDidLoad
{
recordMode = YES;
UIButton *modeChangeButton = [[UIButton alloc] initWithFrame:CGRectMake(200, 450, 60, 60)];
[modeChangeButton setBackgroundImage:[UIImage imageNamed:#"recordmode.PNG"] forState:UIControlStateNormal];
[self.view addSubview:modeChangeButton];
}
When I click the button , the button will change the image. The code is like the following:
- (IBAction)modeButtonClick:(id)sender {
NSLog(#"modeButtonClick..!!!!!!");
if (recordMode == YES) {
NSLog(#"modeButtonClick..%hhd = " , recordMode);
[self.modeChangeButton setBackgroundImage:[UIImage imageNamed:#"photomode.png"] forState:UIControlStateNormal];
recordMode = NO;
}else if (recordMode == NO){
NSLog(#"modeButtonClick..%hhd = " , recordMode);
[self.modeChangeButton setBackgroundImage:[UIImage imageNamed:#"recordmode.png"] forState:UIControlStateNormal];
recordMode = YES;
}
}
When I click the image on the button , the image of the button become dark in color. It seems the button has been press. But the - (IBAction)modeButtonClick:(id)sender didn't called.
When I click the blank space (the side of image) , the button has been press. The - (IBAction)modeButtonClick:(id)sender has been called. And the image also change to other image.
I am sure I have set action in header file and .m file.
The above describe is like the following picture.
It seems the button is cover by image , and the image and the button is not the same.
Why this happened ??
How to solve this problem ?
Thanks in advance.
Couple of changes that you could implement:
First:
Change the setBackgroundImage to setImage.
For example: [self.modeChangeButton setImage: [UIImage imageNamed: #"recordmode.png" forControlState: UIControlStateNormal];
That way, if you have set an image to the button by mistake, this will overwrite it.
Second:
Make sure you have connected your reference outlets (IBOutlet) and actions (IBActions) in Interface builder - whether XIB files, or storyboard. If you don't link the the interface objects there to those in your code, they won't work.
Third:
If it still does not work, try adding this line to your viewDidLoad
[self.modeChangeButton addTarget:self #selector(modeButtonClick:) forControlEvents:UIControlEventTouchUpInside];
Fourth:
Change this line in your viewDidLoad:
UIButton *modeChangeButton = [[UIButton alloc] initWithFrame:CGRectMake(200, 450, 60, 60)];
to:
self.modeChangeButton = [[UIButton alloc] initWithFrame:CGRectMake(200, 450, 60, 60)];
This should solve your problem.
This code is adding a new button on top of your self.modeChangeButton which I'm assuming is coming from a xib or storyboard.
- (void)viewDidLoad
{
recordMode = YES;
UIButton *modeChangeButton = [[UIButton alloc] initWithFrame:CGRectMake(200, 450, 60, 60)];
[modeChangeButton setBackgroundImage:[UIImage imageNamed:#"recordmode.PNG"] forState:UIControlStateNormal];
[self.view addSubview:modeChangeButton];
}
Do this instead...
- (void)viewDidLoad {
self.recordMode = YES;
}
- (void)setRecordMode:(BOOL)recordMode {
_recordMode = recordMode;
UIImage *imageForMode = recordMode ? [UIImage imageNamed:#"photomode.png"] : [UIImage imageNamed:#"recordmode.png"];
[self.modeChangeButton setBackgroundImage:imageForMode forState:UIControlStateNormal];
}
- (IBAction)modeButtonClick:(id)sender {
self.recordMode = !self.recordMode;
}
Check your button size and make the frame size closer to the image size. And try to maintain the two images as like below.
- (void)viewDidLoad
{
UIButton *modeChangeButton = [[UIButton alloc] initWithFrame:CGRectMake(200, 450, 60, 60)];
[modeChangeButton setImage:[UIImage imageNamed:#"recordmode.PNG"] forState:UIControlStateNormal];
[modeChangeButton setImage:[UIImage imageNamed:#"photomode.png"] forState:UIControlStateSelected];
[modeChangeButton addTarget:self action:#selector(modeButtonClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:modeChangeButton];
}
- (IBAction)modeButtonClick:(id)sender
{
sender.selected = !sender.selected;
}
Try modifying you viewDidLoad method as follows.
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton *modeChangeButton = [[UIButton alloc] initWithFrame:CGRectMake(200, 300, 60, 60)];
[modeChangeButton setBackgroundImage:[UIImage imageNamed:#"recordmode.PNG"] forState:UIControlStateNormal];
// You might need to add following two lines into your code.
[modeChangeButton addTarget:self action:#selector(modeButtonClick:) forControlEvents:UIControlEventTouchUpInside];
self.modeChangeButton = modeChangeButton;
[self.view addSubview:modeChangeButton];
}
Above solution should work. As I see, you have referencing property named modeChangeButton in your modeButtonClick: method. But you are not assigning the created button into your property. Also you have to set the action selector to your button.
As a improvement, you can do this to improve performance of your application. Without setting the background image on click event, you can select/deselect the button. With this you don't need to maintain boolean flags, which may introduce new bugs to your application.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIButton *modeChangeButton = [[UIButton alloc] initWithFrame:CGRectMake(200, 300, 60, 60)];
[modeChangeButton setBackgroundImage:[UIImage imageNamed:#"recordmode.png"] forState:UIControlStateNormal];
[modeChangeButton setBackgroundImage:[UIImage imageNamed:#"photomode.png"] forState:UIControlStateSelected];
[modeChangeButton addTarget:self action:#selector(modeButtonClick:) forControlEvents:UIControlEventTouchUpInside];
self.modeChangeButton = modeChangeButton;
[self.view addSubview:modeChangeButton];
}
- (IBAction)modeButtonClick:(id)sender {
NSLog(#"modeButtonClick..!!!!!!");
[self.modeChangeButton setSelected:![self.modeChangeButton isSelected]];
}
Hope this helps.

How to add a UIButton to GLKit View?

I need to add a UIButton on a GLKit view. I am trying the same on the default openGL program that is created by Xcode.
Can some one help me out with this?
I finally figured this out myself. Posting detail just incase someone else is looking at the same problem.
To add a button to your GLKView, add the following code snippet in your ViewController.
- (void)viewDidLoad
{
[super viewDidLoad];
//Initialise GLKView. Set Context, depth format etc.
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0, 0, 10, 10);
[button setTitle:#"Button" forState:UIControlStateNormal];
[button addTarget:self action:#selector(onClick:) forControlEvents:UIControlEventTouchDown];
[button setEnabled:YES];
[self.view addSubview:button];
}
-(void)onClick:(id)sender
{
//Do onClick stuff here
[self resignFirstResponder];
}
-
Hochester

Custom background resulting in custom button not showing

I set my custom background in my AppDelegate.m:
[self.window setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"background.png"]]];
And in my viewcontroller i make my custom button before adding it as a subview:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.mainButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.mainButton setImage:[UIImage imageNamed:#"aButton"] forState:UIControlStateNormal];
[self.mainButton setImage:[UIImage imageNamed:#"aButton"] forState:UIControlStateHighlighted];
[self.mainButton setFrame:CGRectMake(100, 100, 300, 100)];
[self.view addSubview:self.mainButton];
}
Only my background is showing. If I remove the background - the button appears.
[super viewDidLoad];
// Do any additional setup after loading the view.
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:[UIImage imageNamed:#"aButton"] forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:#"aButton"] forState:UIControlStateHighlighted];
[button setFrame:CGRectMake(100, 100, 300, 100)];
[self.view addSubview:button];
And do not forget the extention "aButton.png" "aButton.jpg"...
Set a pattern for UIViewController or just write a line
[self.View bringSubViewToFront:_button]

IBAction & Buttons programmatically

I'm creating buttons programmatically and I then want to add functionality whereby when they are tapped on/pressed, they stay highlighted unless tapped on again. What I'm doing now is creating the buttons and then trying to add an IBAction. However, the issue is I have my button creation in a method and then I'm not sure how to reference the button in my IBAction. Here's my code:
UIButton* testButn = [UIButton buttonWithType:UIButtonTypeCustom];
[testButn setFrame:CGRectMake(0, 135, 40, 38)];
[testButn setImage:[UIImage imageNamed:#"test_butn_un.png"] forState:UIControlStateNormal];
[testButn setImage:[UIImage imageNamed:#"test_butn_pressed.png"] forState:UIControlStateHighlighted];
[testButn addTarget:self action:#selector(staypressed:) forControlEvents:UIControlEventTouchUpInside];
[self.contentview addSubview:testButn
-(IBAction)staypressed:(id)sender{
//Not sure what to do here, since this method doesn't recognize testButn, How do I reference testButn
The sender is testButn. You should change stayPressed's argument type from (id) to (UIButton *)
Unless an action method is connected to several different classes of objects, it's best to replace the id with whatever object class you're using. This can be useful if you're hooking things up in IB, since it won't let you hook it to the wrong kind of object.
The fact that it's not working isn't because it doesn't recognize your button. Your approach is wrong. I think you need to have an action connected to touch down, and maybe set the selected state to YES. In your button definition, you need to set an imageForState: for the selected state. The way you're doing it now, that method isn't called until touch up.
Something like this:
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton* testButn = [UIButton buttonWithType:UIButtonTypeCustom];
[testButn setFrame:CGRectMake(0, 135, 40, 38)];
[testButn setImage:[UIImage imageNamed:#"New_PICT0019.jpg"] forState:UIControlStateNormal];
[testButn setImage:[UIImage imageNamed:#"New_PICT0002.jpg"] forState:UIControlStateSelected];
[testButn addTarget:self action:#selector(stayPressed:) forControlEvents:UIControlEventTouchDown];
[self.view addSubview:testButn];
}
-(void)stayPressed:(UIButton *) sender {
if (sender.selected == YES) {
sender.selected = NO;
}else{
sender.selected = YES;
}
}
You need to cast sender to UIButton.
- (IBAction)staypressed:(id)sender
{
UIButton *theButton = (UIButton*)sender;
//do something to theButton
}
UIButton* testButn = [UIButton buttonWithType:UIButtonTypeCustom];
[testButn setFrame:CGRectMake(0, 135, 40, 38)];
[testButn setImage:[UIImage imageNamed:#"test_butn_un.png"] forState:UIControlStateNormal];
[testButn setImage:[UIImage imageNamed:#"test_butn_pressed.png"] forState:UIControlStateHighlighted];
[testButn addTarget:self action:#selector(staypressed:) forControlEvents:UIControlEventTouchUpInside];
testButn.tag = 1;
[self.contentview addSubview:testButn
-(IBAction)staypressed:(id)sender
{
if ([sender tag]==1)
{
somecodes...
}
}

Resources