Storyboard won't make button action - ios

For some reason I can't drag and drop from my storyboard button into my View Controller class.
All of the classes are named correctly, and I've tried logging out of my computer, shutting it down, and killing the XCode process. Nothing seems to work. Can anyone who's faced this kind of thing before give me any advice?

I think the problem in your case is that you have not set the UIViewController Class in Identity Inspecter . Please refer to the screenshots
Screenhot1:
Screenshot2:
In the first screenshot I am setting the Class of the UIViewController as the name of the Class of my View Controller (in my case the name is 'viewController').
Hope it will help you.

Delete and recreate your View Controller class. That how I fixed it (only got this problem 1 time).
Hope this helps.

If this is your situation, you can do one thing. Just tag your button in xib to identify that specific button. In ViewDidload , you can retrieve your button by below code..
#define YOURBTNTAG 44
for (UIView *subBtn in self.view.subviews)
{
if ([subBtn isKindOfClass:[UIButton class]])
{
if ( subBtn.tag == YOURBTNTAG)
{
self.btn = subBtn;
break;
}
}
}
[self.btn addTarget:self action:#selector(test:) forControlEvents:UIControlEventTouchUpInside];
Note : 1) If your class is correctly defined in Xib, It'll work otherwise cann't.
2) If self.view is nil, You have to delete your xib and create new one to do your work. Because It may have naming(class name or xib name) mistake or other mistake.

Related

iOS: showing/hiding UI elements dynamically

I have an app with a UITableView of results in a center column, and a little search bar at the top. I want to dynamically add/remove a button that says "reset search" and pin it to the top of the view.
There are a couple ways to go about it, and I'm worried that they both look ugly or hacky to me. To wit:
Add the button in the storyboard editor, and show/hide it in code. The trouble is I've already got a bunch of views specified this way in the storyboard, and so positioning/selecting them is a huge pain since they overlap each other.
Add the button in code. Except now my UI is specified in two places: the stuff that's in the storyboard, and the additional modifications that take place in the code.
What's the standard way of doing something like this? And how can I prevent my storyboards from becoming a big mess when I've got buttons/dialogs/etc. that need to be dynamically shown/hidden?
Well my first answer is to not use storyboards in the first place. However, I understand that's not helpful in this case.
If I were you, I would do option 2. It's a one off for this single button and it has a specific use case. It doesn't hurt to specify it in code. The following is for the
.h
#property (nonatomic, strong) UIButton *resetButton;
And
.m
//I'm guessing you're using a VC, so I'd put this in viewDidLoad
self.resetButton = [[UIButton alloc]initWithFrame:YOUR FRAME];
self.resetButton.alpha = 0.0;
//any other styling
[self.view addSubview:self.resetButton];
self.resetButton addTarget:self action:#selector(onReset) forControlEvents:UIControlEventTouchUpInside];
//and then add these three methods
- (void)onReset {
//called when reset button is tapped
}
- (void)showResetButton {
[UIView animateWithDuration:.3 animations:^{
self.resetButton.alpha = 1.0;
}];
}
- (void)hideResetButton {
[UIView animateWithDuration:.3 animations:^{
self.resetButton.alpha = 0.0;
}];
}
I don't know if I have understood, but if you want to hide an object with an action, you can do so :
- (IBAction)myaction:(id)sender
{
self.object1.hidden = false ;
self.object2.hidden = true ;
self.object3.hidden = false ;
}
Both ways are perfect, I personally prefer the Storyboard one because it lets you arrange the button more easily and it's easier to add constraints for auto-layout(if needed) in Interface Builder than in code.
For your second question: If your storyboard is cluttered and views are all over the place, I would suggest that you select your views from the side bar, rather thank trying to click on them. Also, if you want to move the selected view, adjust the coordinates in the Utilities panel instead of dragging it with the mouse.

UIView superview added on self.view returns nil

I check if view is already added/exist, then I need to remove it
if([self.upgradeView superview])
[self.upgradeView removeFromSuperview];
self.upgradeView is added on self.view. but condition returns false and self.upgradeView is never removed.
Is there anything that is missed?
=========================UPDATE====================================
I have added this code in viewwillappear just below the code used to add self.upgradeView on self.view like this
if ([isLoggedInPremiumUser isEqualToString:#"0"])
{
[self createUpgradeFooterView];
}
else
{
if([self.upgradeView superview])
[self.upgradeView removeFromSuperview];
}
When are you doing this if statement? It could be that when this is called the view has not yet been added.
Please provide more of your code including where you add the view and where this if statement is called.
You may want to use UIView's -(BOOL)isDescendantOfView:(UIView *)view; to check if view is added or not.
if(![[self upgradeView] isDescendantOfView:[self view]]) {
[self.view addSubview:[self upgradeView]];
} else {
[[self upgradeView] removeFromSuperview];
}
I had the same problem and was trying to search any answer online but found none. Then I found this but no solution neither. I tried some debugs to print superview at different location in the code. I found out that at first this value is nil but then it's not.
So I think this problem is due to the UIView is not completed loaded, then I searched several topics on how to check if a UIView is loaded. Finally I think I get the solution. If I check the superview property in layoutSubviews function, and set all other properties there. Everything works great!
I know this is an old post, just in case someone is having the same headache.

iOS, stopping a second button being tapped in an outlet collection, when two are tapped?

I have this weird bug, I wouldn't expect users to do this, but as it's a kids app, therefore I need my app to perform well and not do something unexpected. Which it does.
I have an outlet collection for several buttons and an IBAction.
It's possible for someone, using two fingers, to tap two buttons at once.
I've tried this, however it still runs for both.
Can anyone suggest how I work round this problem ?
- (IBAction)btnBtnNum:(id)sender {
for( UIButton *button in self.buttonCollection )
{
if( sender != button )
{
[sender setEnabled:NO];
}
}
If it doesn't break anything else, you should look at the property multipleTouchEnabled.

iOS 7 XCode 5.0 IBAction not called

I have an application developed in iOS4 using XiBs. I got it working all good with iOS6.1 and earlier. But for some buttons, IBAction is not getting called if it is iPhone and iOS 7.0. Also it is working fine with iPad and iOS 7.0. Of course, I am using different Xibs for iPhone and iPad.
Here is the code. It is pretty basic. But just not getting into it.
- (IBAction) didReceiveMapButtonPress {
NSLog(#"IN DID RECEIVE MAP BUTTON PRESS");
if ([self wasReferredFromMap]) {
[[self navigationController] popViewControllerAnimated:YES];
} else {
[self pushMapViewController];
}
}
Many of the developer used custom view to show custom cell on Table view for older version of iOS. If you are one of them, then you will have to face a problem that your button click action will no longer work with iOS7.
How to resolve this:
You have three options:
Option 1: Create the new lay out with new table cell instead of taking view. and put all layouts again in table cell.
I know, this will require a lot of effort.If you don't want to do this, we have a very small hack for it:option 2
Option 2: Create a IBOutlet for your button and add this button as a subview of your cell's content view.
[self.myCell.contentView addSubview:self.btn_click];
The above line of code will add btn_click as a subview of you content view. Now button click action should work.
Option 3:
The best way :
i) Take An outlet UITableViewCell.
ii) Make existing view as subview of new table cell.
iii) Disconnect the connection of custom cell to existing view and connect it to new UITableViewCell.
thats it, Your IBAction will work now.
May be you got the crash with error message that "class is not key value coding - compliant.". Check your old view connection and remove all connection having yellow mark.
When I faced with this problem, I had tons of cells from xibs. That's way I've create the category for UITableViewCell
#implementation UITableViewCell (customs)
- (void)awakeFromNib {
[super awakeFromNib];
[self reAddSubviews];
}
- (void)reAddSubviews {
for (UIView * o_vw in [[[self subviews] objectAtIndex:0] subviews]) {
if (o_vw != self.contentView) {
[o_vw removeFromSuperview];
[self.contentView addSubview:o_vw];
}
}
}
#end
Please make sure the TCell.xib for your UITableViewCell is correct.
Double check if this xib file has "Content view". If you can not see this item, that means your view is not a UITableViewCell, it probably is a UIView.
The correct method is to recreate this XIB file. you can do it like this:
NewFile(User Interface)--->Empty--->Device Family(iphone)--->Save as TCell.xib.
add UITableViewCell
copy your subview from your previous xib file to this view and connect the outlets. http://i.stack.imgur.com/WB4j3.png

iOS: automatic way to tab between text fields

I have a relatively large iPhone application with many views.
I would like implement a next/previous option on my keyboard.
I have managed to implement it UI-wise, with some code examples i saw online, but all of them are assuming we need to add code to each view controller to implement the actual transition between the text fields.
My question is: is there a general way to know, given some text field, who is the next field in order? (i.e without refactoring each of my view controllers)
I ask this question because when i use the iPhone simulator and press the computer's Tab key - the switch between the fields happen, so i wonder if there is a built-in or generic way to implement it on iOS.
clarification:
is there a way of doing it without adding a specific code for each type of view controller? (adding a generic code is acceptable)
I want to write how i solved this problem, with the help of many good answers given to me here :)
First, i could not create fully generic code that creates tab regardless of the view it is in.
Instead i created this thing, which i think is the most generic solution with the firstResponder method not working:
i created custom toolbar with my next/previous/done buttons and appropriate actions delegate.
than i extended UIViewController by adding category "Tab". this category declares a fieldsArray and implements the delegate method.
Now what every specific view controller needs to do (beside importing the category) is to provide this fieldsArray according to its properties and calling the init method which adds the buttons toolbar to this fields
I hope you could benefit from this, and again thanks for all the good answers
you could have a method in a utility class that takes as arguments a textfield and a viewcontroller. then you could use the "tag"-attribute of the textfields to find the next textfield in that viewcotroller, assuming that you assigned the tags accordingly. numbers would be great, i think. a simple callback method in the vc could handle the focus-change. thats about as generic as i can see right now.
This is some generic code that I came up with:
// add a property for the fieldsArray
//add this in viewDidLoad
_fieldsArray = [[NSMutableArray alloc] init];
NSArray *viewsArray = [self.view subviews];
for (id view in viewsArray) {
if ([view isKindOfClass:NSClassFromString(#"UITextField")]) {
[_fieldsArray addObject:view];
}
}
//add this in your action that switches the fields
for (UITextField *field in _fieldsArray) {
if ([field isFirstResponder]) {
if ([fieldsArray lastObject] == field) {
[_fieldsArray[0] becomeFirstResponder];
}else {
NSUInteger nextIndex = [_fieldsArray indexOfObject:field] + 1;
[_fieldsArray[nextIndex] becomeFirstResponder];
}
break;
}
}
Before using it it should be improved.
1) find all subviews of self.view recursively
2) do some checks if the arrays are empty or nil or have just one object in them.
Good luck!

Resources