How to instantiate a Custom UIButton in UITableViewCell - ios

I have a UITableViewCell and my cells contain a UIButton subclass (CoolButton).
I have picked the code of CoolButton from raywenderlich tutorial
available here
In the IB I have created a subclass of the UITableViewCell and I have configured the class of my button to CoolButton and set the property type to Custom and configured the IBOutlet for the CoolButton to my UITableView subclass.
My problem is when cells are created, they get a UIButton instead of a CoolButton. As a consequence when I'm setting the properties of the CoolButton I get a crash with "unrecognized selector".
Why UIButton is instantiated instead of a CoolButton? How can I get my CoolButton in the table?
Thanks,
Séb.

I'm going to guess you are doing something like:
CoolButton *b = [UIButton ...]
You need to create it using the CoolButton class:
CoolButton *b = [CoolButton ....];
Or, if you used IB, that you created a UIButton but used an IBOutlet of CoolButton. You would need to make the actual class of the button you drag into IB CoolButton, which you can do by selecting the button and tapping (I think) the second to the left top tab in the inspector.

Related

Assigning a callback to a UIView's UIButton from the containing UIViewController

Right now I have a UIViewController subclass that is hosting a UIView subclass. This UIView has a UIButton, and I want the touch event to be sent to the UIViewController subclass. Right now I have a getter method in the UIView subclass, so I grab the button and assign it by just using the reference from within the UIViewController subclass.
What's the best approach to achieve this result?
Add the action event to your ViewController
- (IBAction)myButtonPressed:sender;
Now if you're using IB (you should be) just link it up, or if doing this in code then manually create the event link.
[myButton addTarget:self action:#selector(myButtonPressed:) forControlEvents:UIControlEventTouchUpInside];

Refactor UIButton to UILabel in storyboard

I've a view in my storyboard with a lot of UIButton with constraints.
Is there a way to transform these buttons to labels without removing each button and create a label with constraints?
UIButton actually contains a UILabel for displaying its titleLabel. So You can set the button UserInteractionEnabled: property to NO.
UIButton may have border color. So set the border color as clear color.
Make the UIButton as custom type.
As you need to reconfigure the constrains again if you added the labels, you can go for the above solution.
Reason for couldn't change in IB/Storyboard:
You have dragged the UIButton from the library to your view. Even you try to change the class name to UILabel or its subclass it won't change the class name.
because UILabel is just a UIView type, Where as UIButton is UIControl type.
That's why you couldn't change the UIButton class name to UILabel or Subclass of UILabel in IB.
Updates:
No Guarantee/Not Recommended on upcoming XCode release

Defining custom UIViews in storyboard

I want to show my own custom UIView in storyboard. By far I have done following but my custom view is not showing up.
Dragged and dropped a UIView instance in my screen.
Defined the class for this UIView as my custom class.
Have connected this UIView with an IBOutlet in my view controller.
I even tried with below code in viewWillAppear.
self.myView = [[MyCustomView alloc] initWithFrame:frame];
This works if I create an instance of my custom view and add as a subview to my IBOutlet property for my view. So, below code is working but I want to keep track of only my IBOutlet iVar and do not want to play with another object for changes on my custom view:
self.myExtraView = [[MyCustomView alloc] initWithFrame:frame];
[self.myView addSubview:self.myExtraView];
Any idea how to do this in a better way so that I could have just one reference of my custom view and could change properties on it as per will.
Found the issue. With storyboard we must initialize anything in initWithCode method. I was implementing the regular init method.

How to use a custom UIButton category with Interface Builder?

I'm coding a simple card game for my younger sister on a whim. I'm using UIButtons: default state is face down, selected state is face up. I need the buttons to have a boolean property that tells me if they've ever been flipped over. If not, it gets set to true (that way I'm not just drawing random cards on each flip). I tried creating a category of UIButton called CardGameButton. In the .h file:
#interface UIButton (CardGameButton)
#property (nonatomic) BOOL discovered;
#end
In the .m file:
#implementation UIButton (CardGameButton)
#dynamic discovered;
#end
This is really all I need. How do I use this in IB? I have a bunch of UIButtons on a screen that I want to be CardGameButtons. But when I try to switch my calls to UIButton in my view controller to CardGameButton, it tells me CardGameButton isn't a type (yes I imported the file). And when I try to switch the class of the UIButtons in the storyboard to CardGameButtons, the console tells me that they're an "unknown class". I tried subclassing UIButton, but that didn't work (I just need them to be RoundedRectButtons with the extra property, and since you can't subclass RoundedRectButton they wouldn't display properly). How do I make this work in IB?
You're treating CardGameButtons as though it's a subclass of UIButton when instead it's a category. Anything you declare as UIButton will have the discovered property as standard, but you can't 'create' a CardGameButtons as it's not a thing in itself.
Categories are not types. They're just used to add some extended behavior to the class.
I suggest that you try subclassing UIButton and call it CardGameButton. Add the BOOL property to its interface. You can still make it a round rect button, by setting buttonType to UIButtonTypeRoundedRect "round rect buttons aren't a separate subclass.". Then override
- (void)sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event {
if(event.type == UIEventTypeTouches){
self.discovered = YES; // or handle the logic as you want here
}
[super sendAction:action to:target forEvent:event];
}
You can add a UIButton to your view from the IB, and then its class to your created subclass and set its type to round rect.
Edit: As you stated, buttonType is actually readOnly, so we can't use that to draw a round rect button. However, it turns out that it's not hard to draw it.
Check this tutorial. It shows how to do it using CALayer property of UIButton and using UIBezeirPath.

How to set Accessoryview to static UITableViewCell?

I have created a UITableViewController with a UITableView and static UITableViewCells.
How can I change the Accessory View to a custom Image within a UIImageView?
I know how to change the Accessory View generally:
UIImage *accessor = [UIImage imageNamed:#"imageName"];
[somecell setAccessoryView:[[UIImageView alloc] initWithImage: accessor]];
The solution:
Create an IBOutlet for each UITableViewCell which should have a custom accessory view and connect the IBOutlet to the UITableViewCell in the storyboard. After that you can set the accessory view like above.
I found a better solution:
Drag a view (for example a instance of UISwitch) into UITableViewController in storyboard
Selet the cell on which you want to add a custom accessory view. Then open the Connections inspector, drag the accessoryView in section Outlets to the view that you created in step 1.
Now run the app, see a custom accessory view appearing in a static UITableViewCell. Of course you can create another IBOutlet between the UISwitch and controller so that you could get the reference of it, or create an IBAction for receiving action when user change the value of UISwitch.
Add a custom UIButton in the storyboard and set the image you want to it

Resources