I'd like to add a UIButton to a custom UITableViewCell (programmatically). This is easy to do, but I'm finding that the "performance" of the button in the cell is slow - that is, when I touch the button, there is quite a bit of delay until the button visually goes into the highlighted state. The same type of button on a regular UIView is very responsive in comparison.
In order to isolate the problem, I've created two views - one is a simple UIView, the other is a UITableView with only one UITableViewCell. I've added buttons to both views (the UIView and the UITableViewCell), and the performance difference is quite striking.
I've searched the web and read the Apple docs but haven't really found the cause of the problem. My guess is that it somehow has to do with the responder chain, but I can't quite put my finger on it. I must be doing something wrong, and I'd appreciate any help. Thanks.
Demo code:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
#property UITableView* myTableView;
#property UIView* myView;
ViewController.m
#import "ViewController.h"
#import "CustomCell.h"
#implementation ViewController
#synthesize myTableView, myView;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
[self initMyView];
[self initMyTableView];
}
return self;
}
- (void) initMyView {
UIView* newView = [[UIView alloc] initWithFrame:CGRectMake(0,0,[[UIScreen mainScreen] bounds].size.width,100)];
self.myView = newView;
// button on regularView
UIButton* myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[myButton addTarget:self action:#selector(pressedMyButton) forControlEvents:UIControlEventTouchUpInside];
[myButton setTitle:#"I'm fast" forState:UIControlStateNormal];
[myButton setFrame:CGRectMake(20.0, 10.0, 160.0, 30.0)];
[[self myView] addSubview:myButton];
}
- (void) initMyTableView {
UITableView *newTableView = [[UITableView alloc] initWithFrame:CGRectMake(0,100,[[UIScreen mainScreen] bounds].size.width,[[UIScreen mainScreen] bounds].size.height-100) style:UITableViewStyleGrouped];
self.myTableView = newTableView;
self.myTableView.delegate = self;
self.myTableView.dataSource = self;
}
-(void) pressedMyButton {
NSLog(#"pressedMyButton");
}
- (void)viewDidLoad {
[super viewDidLoad];
[[self view] addSubview:self.myView];
[[self view] addSubview:self.myTableView];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CustomCell *customCell = [tableView dequeueReusableCellWithIdentifier:#"CustomCell"];
if (customCell == nil) {
customCell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"CustomCell"];
}
return customCell;
}
#end
CustomCell.h
#import <UIKit/UIKit.h>
#interface CustomCell : UITableViewCell
#property (retain, nonatomic) UIButton* cellButton;
#end
CustomCell.m
#import "CustomCell.h"
#implementation CustomCell
#synthesize cellButton;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// button within cell
cellButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[cellButton addTarget:self action:#selector(pressedCellButton) forControlEvents:UIControlEventTouchUpInside];
[cellButton setTitle:#"I'm sluggish" forState:UIControlStateNormal];
[cellButton setFrame:CGRectMake(20.0, 10.0, 160.0, 30.0)];
[self addSubview:cellButton];
}
return self;
}
- (void) pressedCellButton {
NSLog(#"pressedCellButton");
}
#end
On the table view, under section "scroll view" there is the option "delays content touches"... remove it and the delay on button is gone but in this way table scroll don't start dragging the button.
I don't think it has anything to do with what you're doing (I tested it, and it is a little slow, but I wouldn't call it "sluggish"). It probably has to do with the various gesture recognizers attached to a table view -- the operating system has to figure out what gesture is happening, and that may cause a slight delay. This is the log of tableView.gestureRecognizers:
2012-10-09 20:34:12.355 SlowButtonsInTableView[3635:c07] (
"<UIScrollViewDelayedTouchesBeganGestureRecognizer: 0x71b42b0; state = Possible; delaysTouchesBegan = YES; view = <UITableView 0x789f800>; target= <(action=delayed:, target=<UITableView 0x789f800>)>>",
"<UIScrollViewPanGestureRecognizer: 0x71b4940; state = Possible; delaysTouchesEnded = NO; view = <UITableView 0x789f800>; target= <(action=handlePan:, target=<UITableView 0x789f800>)>>",
"<UISwipeGestureRecognizer: 0x71b4e00; state = Possible; view = <UITableView 0x789f800>; target= <(action=handleSwipe:, target=<UITableView 0x789f800>)>; direction = right,left>",
"<UIGobblerGestureRecognizer: 0x71b5100; state = Possible; enabled = NO; view = <UITableView 0x789f800>>"
)
With scrolling on table view not enabled the delay disappear completely, probably the delay is caused by the gesture necessary for scrolling
Related
I have a UICollectionView that has an array of UICollectionViewCell each cell takes up 80% of the view.
I want to add a static UIButton onto the screen that scrolls to the next cell every time it is pressed, I will have to add the button subview onto the Parent view and not the UICollectionView for it to be static.
My questions are : how do I add the overlay onto the main view and how do I scroll the view programmatically with the press of the button?
Where I implemented my collection view
#interface EvaluationViewController () <UICollectionViewDataSource, UICollectionViewDelegate>
#property (weak, nonatomic) IBOutlet UIBarButtonItem *cancelButton;
#property (nonatomic, strong) DBManager* dbManager;
#end
#implementation EvaluationViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.dbManager = [[DBManager alloc] initWithDatabaseFilename:#"emokitDb.sqlite"];
NSLog(#"self.dbManager %#",self.dbManager.documentsDirectory);
[self loadProjectWithId:1];
}
- (IBAction)cancelButton:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 4;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
Screen * screen = [self.project.screens objectAtIndex:indexPath.row];
static NSString * cellIdentifier = #"EvaluationCell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
return cell;
}
-(void)loadProjectWithId:(int)projectId {
}
#end
It is quite easy:
You can add the button like that:
And you have to give a target to the button to move collectionView contentOffset...
- (void)viewDidLoad
{
[super viewDidLoad];
self.dbManager = [[DBManager alloc] initWithDatabaseFilename:#"emokitDb.sqlite"];
NSLog(#"self.dbManager %#",self.dbManager.documentsDirectory);
[self loadProjectWithId:1];
UIButton * button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(910, 400 , 100, 100);
button.backgroundColor =[UIColor blackColor];
[self.collectionView.superview addSubview:button];
[button addTarget:self action:#selector(changeContentOffset:) forControlEvents:UIControlEventTouchUpInside];
}
Then in the selector you have to implement a method to change contentOffset
- (IBAction)changeContentOffset:(id)sender {
[self.collectionView setContentOffset:CGPointMake(nextCellXValue, 0) animated:YES]
}
What I am trying to do is reveal a hidden menu when swiping on a UITableViewCell.
I have no idea how to do it, any guidance will be appreciated.
Here is an image so that you get an idea:
Image http://imageshack.com/a/img855/9134/j6k8.png
u can do it by using custom cell i give the ruff idea and sample code how to achieve this,
first create a new file objective-c, and name it as CustomCell subclass of UITableViewCell and in CustomCell.h file
i took some dummy views and labels
#import <UIKit/UIKit.h>
#interface CustomCell : UITableViewCell
{
}
#property (nonatomic, retain) UIView *optionsView; //this is your options to show when swiped
#property (nonatomic, retain) UIView *mainVIew; //this is your view by default present on top of options view
#property (nonatomic, retain) UILabel *messageLabel;
#property (nonatomic, retain) UILabel *optionsLabel;
#end
in CustomCell.m
#import "CustomCell.h"
#implementation CustomCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
//since we are not using the xib we hav to initilise hear
_optionsView = [[UIView alloc]init];
_mainVIew = [[UIView alloc]init];
_optionsView.backgroundColor = [UIColor greenColor];
_mainVIew.backgroundColor = [UIColor redColor];
_optionsView.alpha = 0.0f;
_mainVIew.alpha = 1.0f;
_messageLabel = [[UILabel alloc]init];
_optionsLabel = [[UILabel alloc] init];
[_optionsView addSubview:_optionsLabel]; //hear u can add image view or buttons to options view i just added the label
[_mainVIew addSubview:_messageLabel];
//add the gesture to main view
UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(whenSwiped:)];
swipeGesture.direction = UISwipeGestureRecognizerDirectionRight;
[_mainVIew addGestureRecognizer:swipeGesture];//add it to main view
UISwipeGestureRecognizer *swipeReverse = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(whenSwipedReversed:)];
swipeReverse.direction = UISwipeGestureRecognizerDirectionLeft;
[_optionsView addGestureRecognizer:swipeReverse]; //add it to options view so that user can swipe back
[self.contentView addSubview:_optionsView]; //first add the optionsVIew
[self.contentView addSubview:_mainVIew]; //then main view
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)layoutSubviews
{
[super layoutSubviews];
_optionsView.frame = self.bounds;
_mainVIew.frame = self.bounds;
_messageLabel.frame = _mainVIew.bounds;
_optionsLabel.frame = _optionsView.bounds;
_optionsView.alpha = 0.0f;
_mainVIew.alpha = 1.0f;
}
//handle swipe call backs in cell only and make a delegate to controller about the button actions of options view
- (void)whenSwiped:(id)sender
{
CGRect frameRect = _mainVIew.frame;
frameRect.origin.x = 300.0f;
[UIView animateWithDuration:0.5 animations:^{
_mainVIew.frame = frameRect;
_optionsView.alpha = 1.0f;
}];
}
- (void)whenSwipedReversed:(id)sender
{
CGRect frameRect = _mainVIew.frame;
frameRect.origin.x = 0.0f;
[UIView animateWithDuration:0.5 animations:^{
_mainVIew.frame = frameRect;
_optionsView.alpha = 0.0f;
}];
}
#end
in view controller import #import "CustomCell.h"
in datasource method of tableview
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *Cell = [tableView dequeueReusableCellWithIdentifier:#"CELL"];
if(Cell == nil)
{
Cell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"CELL"];
}
Cell.selectionStyle = UITableViewCellSelectionStyleNone;
Cell.optionsLabel.text = #"options";
Cell.messageLabel.text = #"swipe me";
return Cell;
}
above is example, hope this helps u .. :)
and comment if don't get
Here is some guidance:
Each UITableViewCell could have two views, one on top of the other. The top-most view is what is shown by default, and the bottom-most view is what you call the "hidden menu."
You will need to register a UISwipeGestureRecognizer in your storyboard that manages the table cells you are showing above. You will create an IBAction for that gesture recognizer in your custom UITableViewCell class. In that action, you will handle the swipes that occur and then displace the top-most view of the cell by your desire amount, up to a maximum displacement (in the x-direction).
If you need more than this, let me know and I'll provide more info. I can't tell from your original question just how experienced you are, e.g., do you know how to create UITableViews with custom UITableViewCells?
UPDATE:
Make sure that you are creating a XIB file that houses your custom UITableViewCell. Then you can easily add the UISwipeGestureRecognizer to the XIB, and connect it to an IBAction in your cell class. In your UIViewController, you will register the XIB with a reuse identifier and populate your UITableView this way.
The purpose is to implement a fixed search bar just like Contacts in iOS7.
I have a view controller called SearchViewController inherited from UIViewController.
And I add a searchBar and a tableView as its navigationController.view's subView.
But since searchBar and tableView are separated, when I start to search, no dim effect on tableView and result table view is shown in correctly.
I just want it behaves just like Contacts app.
Here is my code:
SearchViewController.h
#import <UIKit/UIKit.h>
#class UWTabBarController;
#class InfoSessionModel;
#interface SearchViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate, UISearchDisplayDelegate>
SearchViewController.m
#import "SearchViewController.h"
#interface SearchViewController ()
#property (nonatomic, strong) UISearchBar *searchBar;
#property (nonatomic, strong) UISearchDisplayController *searchController;
#property (nonatomic, strong) UITableView *tableView;
#property (nonatomic, strong) NSArray *data;
#end
#implementation SearchViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// initiate search bar
NSInteger statusBarHeight = 20;
NSInteger navigationBarHeight = self.navigationController.navigationBar.frame.size.height;
_searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, statusBarHeight + navigationBarHeight, 320, 44)];
// _searchBar.tintColor = [UIColor clearColor];
_searchBar.delegate = self;
_searchBar.barStyle = UIBarStyleDefault;
//NSMutableArray *scopeTitles = [[NSMutableArray alloc] initWithObjects:#"Employer", #"Program", #"Note", nil];
_searchBar.scopeButtonTitles = [[NSArray alloc] initWithObjects:#"Employer", #"Program", #"Note", nil];//[#"Employer|Program|Note" componentsSeparatedByString:#"|"];
// initiate search bar controller
_searchController = [[UISearchDisplayController alloc] initWithSearchBar:_searchBar contentsController:self];
_searchController.delegate = self;
_searchController.searchResultsDataSource = self;
_searchController.searchResultsDelegate = self;
// initiate table view
_tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, statusBarHeight + navigationBarHeight, 320, [UIScreen mainScreen].bounds.size.height - statusBarHeight - navigationBarHeight)];
[_tableView setContentInset:UIEdgeInsetsMake(_searchBar.frame.size.height, 0, _tabBarController.tabBar.frame.size.height, 0)];
_tableView.delegate = self;
_tableView.dataSource = self;
[_tableView registerClass:[InfoSessionCell class] forCellReuseIdentifier:#"InfoSessionCell"];
[_tableView registerClass:[LoadingCell class] forCellReuseIdentifier:#"LoadingCell"];
[self.navigationController.view addSubview:_tableView];
[self.navigationController.view addSubview:_searchBar];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (_searchController.searchResultsTableView == tableView) {
return 1;
}
else {
return [data count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (_searchController.searchResultsTableView == tableView) {
static NSString *cellIdentifier = #"LoadingCell";
LoadingCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[LoadingCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.loadingLabel.text = #"Test cell for search result";
return cell;
}
else {
//... configure cell and return cell
return cell;
}
}
}
#pragma mark - UISearchDisplayController Delegate Methods
// hasn't been implemented
#pragma mark - UISearchBar Delegate Methods
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
//move the search bar up to the correct location
[UIView animateWithDuration:.3
animations:^{
searchBar.frame = CGRectMake(searchBar.frame.origin.x,
20,// status bar's height
searchBar.frame.size.width,
searchBar.frame.size.height);
}
completion:^(BOOL finished){
//whatever else you may need to do
}];
return YES;
}
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar {
//move the search bar down to the correct location
[UIView animateWithDuration:.25
animations:^{
NSInteger statusBarHeight = 20;
NSInteger navigationBarHeight = self.navigationController.navigationBar.frame.size.height;
searchBar.frame = CGRectMake(_searchBar.frame.origin.x,
statusBarHeight + navigationBarHeight,
_searchBar.frame.size.width,
_searchBar.frame.size.height);
}
completion:^(BOOL finished){
//whatever else you may need to do
}];
return YES;
}
This is the effects of my code:
All right, my problem is caused by my misunderstanding of views and navigationController's views.
In view did load method:
before is:
[self.navigationController.view addSubview:_tableView];
[self.navigationController.view addSubview:_searchBar];
but should be:
[self.view addSubview:_tableView];
[self.view addSubview:_searchBar];
In this way, the original table view and result table view will show correctly.
And other things are moving search bar up and down, these things should be done through UISearchBar delegate protocol methods and UISearchDisplayController delegate protocol methods.
This is a right way to implement a fixed searchBar and tableView bellow it.
I have a problem similar to this one but answer provided there doesn't help much.
I have UITableView with some custom UITableViewCells, those cells have some nested custom UIViews and finally some UIButtons inside. The problem, as in question specified above, is that when I touch my button touch event won't populate to UITableView and it never scrolls.
Here's some code (it's just fastest way to reproduce, it's not my actual code):
#interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
#property (strong, nonatomic) IBOutlet UITableView * tableView;
#end
#implementation ViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])
{
self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0,
self.view.bounds.size.width,
self.view.bounds.size.height)
style:UITableViewStylePlain];
[self.view addSubview:self.tableView];
self.tableView.delegate = self;
self.tableView.dataSource = self;
}
return self;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell * cell = [[UITableViewCell alloc] init];
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
button.backgroundColor = [UIColor redColor];
button.frame = CGRectMake(0, 0, 50, 44);
[cell.contentView addSubview:button];
return cell;
}
#end
Red button in the only cell won't let table view to bounce scroll.
Can anyone help me a bit?
P.S. Don't pay attention to the stupidity of the code I've provided, I'm aware of all issues about it. I just provided it to show what the issue is all about. It's the conflict of buttonView and scrollView.
You can change the behaviour by overriding touchesShouldCancelInContentView: in the UITableView. For this to work you'll need to replace the table view with this subclass, either in loadView or in your xib file.
#interface AutoCancelTableView: UITableView
#end
#implementation AutoCancelTableView
//
// Overriding touchesShouldCanceInContentView changes the behaviour
// of button selection in a table view to act like cell selection -
// dragging while clicking a button will cancel the click and allow
// the scrolling to occur
//
- (BOOL)touchesShouldCancelInContentView:(UIView *)view {
return YES;
}
#end
This is the standard behaviour of UIScrollView which tableviews use. The system doesn't know that you want to scroll until you move your finger, but by that time you have already "pressed" on the button and so it assumes that's what you want to do.
You can play with a couple of properties on your tableview's scrollview to change the behaviour, but you may find they negatively impact the feel of your cells and buttons because of added delays.
self.tableView.delaysContentTouches = YES;
delaysContentTouches
If the value of this property is YES, the scroll view delays handling the touch-down gesture until it can determine if scrolling is the intent...
and
self.tableView.canCancelContentTouches = YES
canCancelContentTouches
If the value of this property is YES and a view in the content has begun tracking a finger touching it, and if the user drags the finger enough to initiate a scroll, the view receives a touchesCancelled:withEvent: message and the scroll view handles the touch as a scroll.
Because all the above answers not working for me. I add a imageView on the button and make the imageView user interface YES, then add a tap gesture on the iamgeView. In the tap gesture related methods I put the button related methods in. so all is well..
may be hack. But it work well..
Below code works for me:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
cell = [tableView dequeueReusableCellWithIdentifier:#"cell_id"];
cell.userInteractionEnabled = YES;
if (cell == nil) {
cell = [[[CustomCell1 alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell_id"]autorelease];
}
[cell.button addTarget:self action:#selector(button_action) forControlEvents:UIControlEventTouchUpInside];}
-(void)button_action{NSLog(#"Hello!");}
This is my custom cell:
#import "CustomCell.h"
#implementation CustomCell
#synthesize button;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
button = [[UIButton alloc]init];
button =[UIColor redColor];
[self.contentView addSubview: button];
}
return self;}
- (void)layoutSubviews {
[super layoutSubviews];
CGRect contentRect = self.contentView.bounds;
CGFloat boundsX = contentRect.origin.x;
CGRect frame;
frame= CGRectMake(boundsX+50 ,+15, 100, 100);
button = frame;}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{ [super setSelected:selected animated:animated];
// Configure the view for the selected state
}
there is this dark sorcery in ios is preventing my button being clicked. if i don't add button to the uitableviewcell, and i click the button, the event is triggered.
but if the button is in uitableviewcell, it won't get triggered, it seems table
i have sample code ready, if you guys can help me, please just create a simple single-view application in xcode, and just paste the following code
//GRDViewController.h
#import <UIKit/UIKit.h>
#interface GRDViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, strong) UIView* container;
#property (nonatomic, strong) UIButton* button;
#property (nonatomic, strong) UITableView* tableView;
#property (nonatomic, strong) NSArray* arr;
#end
//GRDViewController.m
#import "GRDViewController.h"
#implementation GRDViewController
#synthesize button, container, arr, tableView;
- (void)_btnTapped {
NSLog(#"TAPPED");
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.button = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
[self.button addTarget:self action:#selector(_btnTapped) forControlEvents:UIControlEventTouchUpInside];
[self.button setTitle:#"CLICK ME" forState:UIControlStateNormal];
self.arr = [[NSArray alloc] initWithObjects:#"123", #"456", #"678", nil];
self.container = [[UIView alloc]initWithFrame:self.button.frame];
[self.container addSubview:self.button];
[self.view addSubview:self.container];
//[self.view addSubview:self.button];
self.tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 100, 400, 400)];
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.view addSubview:self.tableView];
self.tableView.backgroundColor = [UIColor redColor];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"coolcell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
//cell.accessoryType = UITableViewCellAccessoryNone;
UIButton * btn = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 50, 50)];
[btn addTarget:self action:#selector(_btnTapped) forControlEvents:UIControlStateNormal];
[btn setTitle:[self.arr objectAtIndex:[indexPath row]] forState:UIControlStateNormal];
[cell.contentView addSubview:btn];
}
return cell;
}
- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section {
return [self.arr count];
}
#end
please help
i feel this case should be common in ios, but nobody has solution for this???
edit: when click on the button it prints NSLOG msg in the xcode console...so make sure...u r looking at the results there...
you have not given any control event to button .Change it to UIControlEventTouchUpInside from UIControlStateNormal
Instead of using UIControlStateNormal for ControlEvents use UIControlEventTouchUpInside like this
[btn addTarget:self action:#selector(_btnTapped) forControlEvents:UIControlEventTouchUpInside];
Try doing this:
[btn.titleLabel setUserInteractionEnabled: NO];