I have created a UICollection View inside a storyboard, I have created a button inside the cell, whenever I tap on the button I should filter the data as per my condition, so each and every buttons inside the cell will have different conditions, can anyone help me out with this issue ?? Iam using xcode 9 and swift 4.
Use addTarget of your button inside cellForItemAt:indexPath datasource and add a selector where action of the button will be defined. Add this button's tag, (add it same as your indexPath.row, that you can use to differentiate your button from collectionview)
cell.yourButton.addTarget(self, action: #selector(yourButtonTapped), for: .touchUpInside)
cell.yourButton.tag = indexPath.row
Now add the action of that button and inside that perform any action you need.
#IBAction func yourButtonTapped(_ sender: UIButton) {
//perform action
}
Create a custom UICollectionViewCell type. Wire up an IBAction to the cell.
Create a protocol that lets the cell notify the collection view that the user tapped a button. Have the action pass the tap to the delegate.
In your cellForItemAt() method, set the view controller as the delegate.
Now in your view controller handle the tap as desired.
Try this for Objective c
Add below code at cellForRowAtIndexPath
cell.btnOk.tag = indexPath.row ;
[cell.btnOk addTarget:self action:#selector(OkBtnAction:) forControlEvents:UIControlEventTouchUpInside] ;
Than add the action of that button
-(IBAction)OkBtnAction:(id)sender
{
UIButton* btn=(UIButton*)sender;
NSLog(#"row: %ld",(long)btn.tag);
}
Related
I'm having a TableView. In that tableView, I custom it's cells
like this
In this cell I have 2 part. An Image and an TextField.
It's look like facebook's post status. When I click to Image, I want to open a new ViewController and the same for TextField
But I have a problem that I can't call segue from my cell's class file.
Are there any way that I can call a function in TableViewController's class from TableViewCell's class ?
I know that I can use delegate but I don't like this way a lot, because if I do this way I have to set a lot of delegate in my project.
Are there any better way to present a new ViewController directly from TableViewCell's class
Using a delegate is a very good way to solve your problem.
If you don't like that solution then you could design a table view cell that has a closure property set by the view controller, and invokes that closure when the button is pressed.
EDIT:
Another alternative is to leave the button action empty in your custom cell, but still connect up outlets to the buttons.
Then in your cellForRow(at:) method, install an IBAction that has your view controller as the target. (Credit to #SoanSani, who's answer is below)
In that IBAction method, you can use the coordinates of the button to figure out the indexPath of the cell hat contains the button that was tapped.
I've created an extension to UITableView that lets you figure out the cell that contains any view. The code is below:
import UIKit
public extension UITableView {
/**
This method returns the indexPath of the cell that contains the specified view
- Parameter view: The view to find.
- Returns: The indexPath of the cell containing the view, or nil if it can't be found
*/
func indexPathForView(_ view: UIView) -> IndexPath? {
let origin = view.bounds.origin
let viewOrigin = self.convert(origin, from: view)
let indexPath = self.indexPathForRow(at: viewOrigin)
return indexPath
}
}
You can use delegates, but if you dont want to use delegates
while setting up the cell add target to your button tableViewController class and then you can receive all events in tableview class rather than cell class.
But this would require to add tags which you can use to differentiate which button in cell was clicked
Objective C Code
[OkBtn addTarget:self action:#selector(okButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
Swift Code
OkBtn.addTarget(self, action: #selector(ViewController.okButtonTapped), for: .TouchUpInside)
I'm using collectionView, and I customized the collectionViewCell in a separate class with type (collectionViewCell). I want to perform an animation when user clicks on a cell. So, I created a UIButton in collectionViewCell and I customized it to cover the whole cell.
button = UIButton(frame: self.frame)
button.addTarget(self, action: "scaleToSmall", forControlEvents: .TouchDown)
self.addSubview(button)
Right now, the animation works perfectly, but the issue is I lost the ability select the cell, and the function didSelectItemAtIndexPath does not call anymore
I found out how to get the indexPath of the cell that has clicked,
But how can I call didSelectItemAtIndexPath again and tell it this cell is selected in order to perform the next action (segue to another ViewController) ???
Thanks in advance!!
You said that you created a button that covers the whole cell, if I have that right. Because of that, didSelectRowAtIndexPath won't do anything because that button is covering the whole cell. Take the Twitter app, for example. You can tap on the cell to open the tweet or you can tap on the user's profile image to open their profile. In this case, it's like you have the profile picture button covering the whole cell. Maybe you can set the animation in didSelectRowAtIndexPath or make the button smaller.
Hope this helps!
I created a custom UITableViewCell in a separate nib, and inside it I have a button. I want the tableViewCell to segue to one view controller when the cell is tapped, but a different one when the button is tapped. The cell tap segue works fine, but I can't figure out how to setup a segue between the button in the cell and the next view. I have added a target to the button with
cell.imagePreview.addTarget(self, action: "segueToImageView:", forControlEvents: .TouchUpInside)
Then in that method
#IBAction func segueToImageView(sender: UIButton) {
performSegueWithIdentifier("ImageViewSegue", sender: self)
}
But obviously I end up with a "has no segue with identifier 'ImageViewSegue'" error. I tried connecting the button to the new view in my main.storyboard, but it won't let me drag between the nib and the storyboard. I also tried creating a segue in main.storyboard between the two views and calling it "ImageViewSegue" but I get the same error.
Is there a way to create a segue with identifier through code? If not, how should I go about segueing to the new view via the button?
Instead of a segue, just do this the old-fashioned way (from before there were storyboards and segues): set the button's action–target pair (in code, when you load) so that when the button is tapped, your action handler is called. In the action handler, do whatever the segue would do, i.e. instantiate the view controller from the storyboard and push or present it.
I can't seem to handle a button click properly inside a custom UITableViewCell. It's a cell that contains a label and a button. I have the following code:
var cell = tableView.DequeueReusableCell (cellKey) as ApptHistoryCell;
if (cell == null)
{
cell = _container.Cell;
cell.SelectionStyle = UITableViewCellSelectionStyle.None;
}
if (InfoClicked != null)
{
cell.ActionButton.TouchUpInside += InfoClicked;
}
InfoClicked is an event handler passed on in loop on cell creation. When the cell is re-used, this causes a null reference exception, because (I think) TouchUpInside is trying to call 2 handlers. Old one and the new one, which causes a crash. If I put the event handler inside cell == null if block, then the wrong action is shown.
How can I handle the click properly?
Thanks!
The way I handle buttons inside custom cells:
I define an IBAction that I connect to a UIButton event inside the custom cell
I define a delegate and a delegate method for the cell to handle the button action
The IBAction calls that delegate method
When defining your cells in cellAtRow... I set the tableViewController to be the delegate. cell.delegate=self;
I do whatever action I would like to do inside that delegate method in the tableViewController
Makes sense?
you should create your cell from a xib file, which already connects the buttons to the owner's targets (the view controller).
In your custom cell just locate your button at IB and make connection with the property.
Now, in the controller at cellForRowAtIndexPath, what you need, just tag that button, say:
(MyCustomCell*)cell.myButton = indexPath.row;
Now, after that just set the click event like that:-
[(MyCustomCell*)cell.myButton addTarget:self action:#selector(NeedFunctionToCall:) forControlEvents:UIControlEventTouchUpInside];
Now, at same view controller, implement that required method, like that:
-(void)NeedFunctionToCall:(id)sender
{
NSLog("Got the event :-> %d, from the cell/button",[sender tag]);
}
I have a 'Load More' UIButton inside a custom UITableViewCell. My table also uses a Delegate. I want to reload the table data when this button is clicked. I have noticed that when I click the button, nothing happens. But when I click on the area around the button i.e. the actual Cell, the Delegate gets the RowSelected event.
I tried using SetSelected(true,false); from the button's touch up inside event to see if it would fire the RowSelected event for the delegate, but it didn't.
Can anyone explain me how I can make a button click for a Custom Table cell fire the actual Row Selected event? If this isn't a viable option, is there a better way to 'Load more data' other than placing the button inside a custom table view cell?
Thanks!
UPDATE:
I do use ContentView.AddSubView as shown in the code below. Please note I'm using Monotouch, but the logic is the same:
public LoadMoreCell (string reuseCellIdentifier)
:base(UITableViewCellStyle.Default, reuseCellIdentifier)
{
SelectionStyle = UITableViewCellSelectionStyle.None;
_btnLoadMore = UIButton.FromType(UIButtonType.RoundedRect);
_btnLoadMore.Frame = new RectangleF(10,5,300,30);
_btnLoadMore.SetTitle("Load More", UIControlState.Normal);
_btnLoadMore.UserInteractionEnabled = true;
ContentView.AddSubview(_btnLoadMore);
}
I have a TableDelegate that has a RowSelected method where I reload the data...however, the RowSelected only gets fired when I click the actual row.
I think you might have added the uibutton as
[self addSubView:yourButton];
instead use :-
[self.contentView addSubview:yourButton];
and all the other controls of your custom cell.
Do this in the initializer of your custom cell :-
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {}
make a custom UITableViewDataSource for your table
and when you hit the button 'Load more', call a method of this datasource to add other data to the list of the datasource, add this datasource to your table and make sure to reload the data of the table
this.tblData.ReloadData ();