UI 테이블 보기에서 누른 UI 버튼 감지
나는 있습니다UITableView
5와 함께UITableViewCells
에는 각셀다음을포다니합함은▁a다▁contains가 있습니다.UIButton
다음과 같이 설정됩니다.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier = @"identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
[cell autorelelase];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 5, 40, 20)];
[button addTarget:self action:@selector(buttonPressedAction:) forControlEvents:UIControlEventTouchUpInside];
[button setTag:1];
[cell.contentView addSubview:button];
[button release];
}
UIButton *button = (UIButton *)[cell viewWithTag:1];
[button setTitle:@"Edit" forState:UIControlStateNormal];
return cell;
}
: ▁the.buttonPressedAction:
방법, 어떤 버튼이 눌렸는지 어떻게 알 수 있습니까?태그를 사용하는 것을 고려해 보았지만, 이것이 가장 좋은 경로인지는 잘 모르겠습니다.어떻게든 태그를 달 수 있으면 좋겠습니다.indexPath
통제하에.
- (void)buttonPressedAction:(id)sender
{
UIButton *button = (UIButton *)sender;
// how do I know which button sent this message?
// processing button press for this row requires an indexPath.
}
이것을 하는 표준적인 방법은 무엇입니까?
편집:
저는 다음과 같은 방법으로 그것을 해결했습니다.저는 여전히 이것이 표준적인 방법인지 아니면 더 나은 방법이 있는지 의견을 가지고 싶습니다.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier = @"identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
[cell autorelelase];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 5, 40, 20)];
[button addTarget:self action:@selector(buttonPressedAction:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:button];
[button release];
}
UIButton *button = (UIButton *)[cell.contentView.subviews objectAtIndex:0];
[button setTag:indexPath.row];
[button setTitle:@"Edit" forState:UIControlStateNormal];
return cell;
}
- (void)buttonPressedAction:(id)sender
{
UIButton *button = (UIButton *)sender;
int row = button.tag;
}
주의할 점은 셀이 대신 대기열에서 해제될 수 있기 때문에 셀 작성 시 태그를 설정할 수 없습니다.그것은 매우 더러운 느낌입니다.더 좋은 방법이 있을 겁니다.
Apple의 액세서리 샘플에는 다음 방법이 사용됩니다.
[button addTarget:self action:@selector(checkButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
그런 다음 터치 핸들러에서 검색된 터치 좌표와 인덱스 경로가 해당 좌표에서 계산됩니다.
- (void)checkButtonTapped:(id)sender
{
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
if (indexPath != nil)
{
...
}
}
셀의 indexPath에 대한 참조를 얻기 위해 superview의 superview를 사용하는 방법이 완벽하게 작동한다는 것을 알게 되었습니다.팁 링크 텍스트에 대해 iphonedevbook.com (맥스미스)에게 감사드립니다.
-(void)buttonPressed:(id)sender {
UITableViewCell *clickedCell = (UITableViewCell *)[[sender superview] superview];
NSIndexPath *clickedButtonPath = [self.tableView indexPathForCell:clickedCell];
...
}
제가 하는 방법은 이렇습니다.단순하고 간결함:
- (IBAction)buttonTappedAction:(id)sender
{
CGPoint buttonPosition = [sender convertPoint:CGPointZero
toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
...
}
Swift 4.2와 iOS 12를 사용하면 문제를 해결하기 위해 다음 5가지 예제 중 하나를 선택할 수 있습니다.
# #1 사용하기 사용하기UIView
의convert(_:to:)
그리고.UITableView
의indexPathForRow(at:)
import UIKit
private class CustomCell: UITableViewCell {
let button = UIButton(type: .system)
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
button.setTitle("Tap", for: .normal)
contentView.addSubview(button)
button.translatesAutoresizingMaskIntoConstraints = false
button.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
button.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
button.topAnchor.constraint(equalToSystemSpacingBelow: contentView.topAnchor, multiplier: 1).isActive = true
button.leadingAnchor.constraint(greaterThanOrEqualToSystemSpacingAfter: contentView.leadingAnchor, multiplier: 1).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
import UIKit
class TableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(CustomCell.self, forCellReuseIdentifier: "CustomCell")
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell
cell.button.addTarget(self, action: #selector(customCellButtonTapped), for: .touchUpInside)
return cell
}
@objc func customCellButtonTapped(_ sender: UIButton) {
let point = sender.convert(CGPoint.zero, to: tableView)
guard let indexPath = tableView.indexPathForRow(at: point) else { return }
print(indexPath)
}
}
# #2 사용하기 사용하기UIView
의convert(_:to:)
그리고.UITableView
의indexPathForRow(at:)
으)로 표시)
이것은 우리가 통과하는 이전의 예에 대한 대안입니다.nil
에▁target
변수는 의매변수에 있습니다.addTarget(_:action:for:)
이렇게 하면 첫 번째 응답자가 작업을 구현하지 않으면 적절한 구현이 발견될 때까지 응답자 체인의 다음 응답자에게 전송됩니다.
import UIKit
private class CustomCell: UITableViewCell {
let button = UIButton(type: .system)
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
button.setTitle("Tap", for: .normal)
button.addTarget(nil, action: #selector(TableViewController.customCellButtonTapped), for: .touchUpInside)
contentView.addSubview(button)
button.translatesAutoresizingMaskIntoConstraints = false
button.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
button.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
button.topAnchor.constraint(equalToSystemSpacingBelow: contentView.topAnchor, multiplier: 1).isActive = true
button.leadingAnchor.constraint(greaterThanOrEqualToSystemSpacingAfter: contentView.leadingAnchor, multiplier: 1).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
import UIKit
class TableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(CustomCell.self, forCellReuseIdentifier: "CustomCell")
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell
return cell
}
@objc func customCellButtonTapped(_ sender: UIButton) {
let point = sender.convert(CGPoint.zero, to: tableView)
guard let indexPath = tableView.indexPathForRow(at: point) else { return }
print(indexPath)
}
}
# #3 사용하기 사용하기UITableView
의indexPath(for:)
패턴
이 예에서는 보기 컨트롤러를 셀의 대리자로 설정합니다.셀의 버튼을 누르면 해당 대리자의 메서드에 대한 호출이 트리거됩니다.
import UIKit
protocol CustomCellDelegate: AnyObject {
func customCellButtonTapped(_ customCell: CustomCell)
}
class CustomCell: UITableViewCell {
let button = UIButton(type: .system)
weak var delegate: CustomCellDelegate?
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
button.setTitle("Tap", for: .normal)
button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
contentView.addSubview(button)
button.translatesAutoresizingMaskIntoConstraints = false
button.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
button.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
button.topAnchor.constraint(equalToSystemSpacingBelow: contentView.topAnchor, multiplier: 1).isActive = true
button.leadingAnchor.constraint(greaterThanOrEqualToSystemSpacingAfter: contentView.leadingAnchor, multiplier: 1).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc func buttonTapped(sender: UIButton) {
delegate?.customCellButtonTapped(self)
}
}
import UIKit
class TableViewController: UITableViewController, CustomCellDelegate {
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(CustomCell.self, forCellReuseIdentifier: "CustomCell")
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell
cell.delegate = self
return cell
}
// MARK: - CustomCellDelegate
func customCellButtonTapped(_ customCell: CustomCell) {
guard let indexPath = tableView.indexPath(for: customCell) else { return }
print(indexPath)
}
}
# #4 사용하기 사용하기UITableView
의indexPath(for:)
위임을 위한 .
이는 프로토콜 대표자 선언 대신 폐쇄를 사용하여 버튼 탭을 처리하는 이전 예제의 대안입니다.
import UIKit
class CustomCell: UITableViewCell {
let button = UIButton(type: .system)
var buttontappedClosure: ((CustomCell) -> Void)?
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
button.setTitle("Tap", for: .normal)
button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
contentView.addSubview(button)
button.translatesAutoresizingMaskIntoConstraints = false
button.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
button.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
button.topAnchor.constraint(equalToSystemSpacingBelow: contentView.topAnchor, multiplier: 1).isActive = true
button.leadingAnchor.constraint(greaterThanOrEqualToSystemSpacingAfter: contentView.leadingAnchor, multiplier: 1).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc func buttonTapped(sender: UIButton) {
buttontappedClosure?(self)
}
}
import UIKit
class TableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(CustomCell.self, forCellReuseIdentifier: "CustomCell")
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell
cell.buttontappedClosure = { [weak tableView] cell in
guard let indexPath = tableView?.indexPath(for: cell) else { return }
print(indexPath)
}
return cell
}
}
# #5 사용하기 사용하기UITableViewCell
의accessoryType
그리고.UITableViewDelegate
의tableView(_:accessoryButtonTappedForRowWith:)
가 단가다경우인 UITableViewCell
의 표준 액세서리 컨트롤, 탭하면 호출이 트리거됩니다.UITableViewDelegate
의tableView(_:accessoryButtonTappedForRowWith:)
관련 인덱스 경로를 가져올 수 있습니다.
import UIKit
private class CustomCell: UITableViewCell {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
accessoryType = .detailButton
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
import UIKit
class TableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(CustomCell.self, forCellReuseIdentifier: "CustomCell")
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell
return cell
}
override func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) {
print(indexPath)
}
}
다른 곳에서 이 문제에 대한 좋은 해결책을 찾았고, 버튼에 있는 태그를 만지작거리지 않았습니다.
- (void)buttonPressedAction:(id)sender {
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint: currentTouchPosition];
// do stuff with the indexPath...
}
다음과 같은 정보를 보내는 것은 어떻습니까?NSIndexPath
에 시대에UIButton
런타임 주입을 사용합니다.
가져오기에 런타임이 필요합니다.
정적 상수 추가
을 더하다NSIndexPath
다음을 사용하여 실행 시 단추로 이동:
(void)setMetaData:(id)object:(id)newObj로 대상 설정
버튼에서 다음을 사용하여 메타데이터 가져오기를 누릅니다.
(id)metaData: (id)target
즐거운 시간 되세요.
#import <objc/runtime.h>
static char const * const kMetaDic = "kMetaDic";
#pragma mark - Getters / Setters
- (id)metaData:(id)target {
return objc_getAssociatedObject(target, kMetaDic);
}
- (void)setMetaData:(id)target withObject:(id)newObj {
objc_setAssociatedObject(target, kMetaDic, newObj, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
#On the cell constructor
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
....
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
....
[btnSocial addTarget:self
action:@selector(openComments:)
forControlEvents:UIControlEventTouchUpInside];
#add the indexpath here or another object
[self setMetaData:btnSocial withObject:indexPath];
....
}
#The action after button been press:
- (IBAction)openComments:(UIButton*)sender{
NSIndexPath *indexPath = [self metaData:sender];
NSLog(@"indexPath: %d", indexPath.row);
//Reuse your indexpath Now
}
To Do (@Vladimir)의 대답은 Swift입니다.
var buttonPosition = sender.convertPoint(CGPointZero, toView: self.tableView)
var indexPath = self.tableView.indexPathForRowAtPoint(buttonPosition)!
확인해보긴 했지만,indexPath != nil
내게 손가락을...."NSIndexPath() NSString 파일은 다음과 같습니다."
func buttonAction(sender:UIButton!)
{
var position: CGPoint = sender.convertPoint(CGPointZero, toView: self.tablevw)
let indexPath = self.tablevw.indexPathForRowAtPoint(position)
let cell: TableViewCell = tablevw.cellForRowAtIndexPath(indexPath!) as TableViewCell
println(indexPath?.row)
println("Button tapped")
}
말씀하신 대로 태그 속성을 사용하여 태그를 다음과 같이 설정합니다.
[button setTag:indexPath.row];
그런 다음 다음 다음과 같이 버튼PressedAction 안에 태그를 넣습니다.
((UIButton *)sender).tag
또는
UIButton *button = (UIButton *)sender;
button.tag;
술잡를좋아만지하, 어떤 하고 싶지 를 만들 수 .NSArray
사전 제작된 버튼:
NSArray* buttons ;
그런 다음 표를 렌더링하기 전에 단추를 만듭니다. 보기 및 배열로 밀어넣습니다.
에 에그음안에다 에.tableView:cellForRowAtIndexPath:
수 있는 : 예를 들어, 다음과 같습니다.
UIButton* button = [buttons objectAtIndex:[indexPath row] ] ;
[cell.contentView addSubview:button];
다음에그에서.buttonPressedAction:
를 할 수 .
- (void)buttonPressedAction:(id)sender {
UIButton* button = (UIButton*)sender ;
int row = [buttons indexOfObject:button] ;
// Do magic
}
섹션 처리 - 사용자 지정 UITableViewCell에 NSIndexPath를 저장했습니다.
CLKIndex 가격HEADERTableCell.xib 보기
INIB에서 XIB에 UI 버튼 추가 - 액션 추가 안 함!
outlet @property(유지, 비원자) IOButlet UIButton *버튼 추가인덱스 섹션 닫기;
IB에서 Ctrl+Drag를 사용하지 마십시오(아래 코드에서 수행).
@interface CLKIndexPricesHEADERTableViewCell : UITableViewCell
...
@property (retain, nonatomic) IBOutlet UIButton *buttonIndexSectionClose;
@property (nonatomic, retain) NSIndexPath * indexPathForCell;
@end
inviewForHeaderInSection(cellForRow에 대해서도 작동해야 함...)테이블에 섹션이 하나만 있는 경우 등)
- viewForHeaderInSection is called for each section 1...2...3
- get the cell CLKIndexPricesHEADERTableViewCell
- getTableRowHEADER just does the normal dequeueReusableCellWithIdentifier
- STORE the indexPath IN the UITableView cell
- indexPath.section = (NSInteger)section
- indexPath.row = 0 always (we are only interested in sections)
- (UIView *) tableView:(UITableView *)tableView1 viewForHeaderInSection:(NSInteger)section {
//Standard method for getting a UITableViewCell
CLKIndexPricesHEADERTableViewCell * cellHEADER = [self getTableRowHEADER];
...섹션을 사용하여 셀에 대한 데이터를 가져옵니다.
...채워주세요.
indexName = ffaIndex.routeCode;
indexPrice = ffaIndex.indexValue;
//
[cellHEADER.buttonIndexSectionClose addTarget:self
action:@selector(buttonDELETEINDEXPressedAction:forEvent:)
forControlEvents:UIControlEventTouchUpInside];
cellHEADER.indexPathForCell = [NSIndexPath indexPathForRow:0 inSection:section];
return cellHEADER;
}
사용자가 섹션 헤더에서 DELETE 버튼을 누르면 호출됩니다.
- (void)buttonDELETEINDEXPressedAction:(id)sender forEvent:(UIEvent *)event
{
NSLog(@"%s", __PRETTY_FUNCTION__);
UIView * parent1 = [sender superview]; // UiTableViewCellContentView
//UIView *myContentView = (UIView *)parent1;
UIView * parent2 = [parent1 superview]; // custom cell containing the content view
//UIView * parent3 = [parent2 superview]; // UITableView containing the cell
//UIView * parent4 = [parent3 superview]; // UIView containing the table
if([parent2 isMemberOfClass:[CLKIndexPricesHEADERTableViewCell class]]){
CLKIndexPricesHEADERTableViewCell *myTableCell = (CLKIndexPricesHEADERTableViewCell *)parent2;
//UITableView *myTable = (UITableView *)parent3;
//UIView *mainView = (UIView *)parent4;
NSLog(@"%s indexPath.section,row[%d,%d]", __PRETTY_FUNCTION__, myTableCell.indexPathForCell.section,myTableCell.indexPathForCell.row);
NSString *key = [self.sortedKeysArray objectAtIndex:myTableCell.indexPathForCell.section];
if(key){
NSLog(@"%s DELETE object at key:%@", __PRETTY_FUNCTION__,key);
self.keyForSectionIndexToDelete = key;
self.sectionIndexToDelete = myTableCell.indexPathForCell.section;
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Remove Index"
message:@"Are you sure"
delegate:self
cancelButtonTitle:@"No"
otherButtonTitles:@"Yes", nil];
alertView.tag = kALERTVIEW_REMOVE_ONE_INDEX;
[alertView show];
[alertView release];
//------
}else{
NSLog(@"ERROR: [%s] key is nil for section:%d", __PRETTY_FUNCTION__,myTableCell.indexPathForCell.section);
}
}else{
NSLog(@"ERROR: [%s] CLKIndexPricesHEADERTableViewCell not found", __PRETTY_FUNCTION__);
}
}
이 예에서는 삭제 버튼을 추가했으므로 확인하려면 UIAertView를 표시해야 합니다.
섹션과 키를 VC의 ivar에 섹션에 대한 정보를 저장하는 사전에 저장합니다.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if(alertView.tag == kALERTVIEW_REMOVE_ONE_INDEX){
if(buttonIndex==0){
//NO
NSLog(@"[%s] BUTTON:%d", __PRETTY_FUNCTION__,buttonIndex);
//do nothing
}
else if(buttonIndex==1){
//YES
NSLog(@"[%s] BUTTON:%d", __PRETTY_FUNCTION__,buttonIndex);
if(self.keyForSectionIndexToDelete != nil){
//Remove the section by key
[self.indexPricesDictionary removeObjectForKey:self.keyForSectionIndexToDelete];
//sort the keys so sections appear alphabetically/numbericsearch (minus the one we just removed)
[self updateTheSortedKeysArray];
//Delete the section from the table using animation
[self.tableView beginUpdates];
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:self.sectionIndexToDelete]
withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
//required to trigger refresh of myTableCell.indexPathForCell else old values in UITableViewCells
[self.tableView reloadData];
}else{
NSLog(@"ERROR: [%s] OBJECT is nil", __PRETTY_FUNCTION__);
}
}
else {
NSLog(@"ERROR: [%s] UNHANDLED BUTTON:%d", __PRETTY_FUNCTION__,buttonIndex);
}
}else {
NSLog(@"ERROR: [%s] unhandled ALERTVIEW TAG:%d", __PRETTY_FUNCTION__,alertView.tag);
}
}
A better way would be to subclass your button and add a indexPath property to it.
//Implement a subclass for UIButton.
@interface NewButton:UIButton
@property(nonatomic, strong) NSIndexPath *indexPath;
Make your button of type NewButton in the XIB or in the code whereever you are initializing them.
Then in the cellForRowAtIndexPath put the following line of code.
button.indexPath = indexPath;
return cell; //As usual
Now in your IBAction
-(IBAction)buttonClicked:(id)sender{
NewButton *button = (NewButton *)sender;
//Now access the indexPath by buttons property..
NSIndexPath *indexPath = button.indexPath; //:)
}
저에게도 효과가 있어요, 고마워요 @Cocanut.
셀의 indexPath에 대한 참조를 얻기 위해 superview의 superview를 사용하는 방법이 완벽하게 작동한다는 것을 알게 되었습니다.팁 링크 텍스트에 대해 iphonedevbook.com (맥스미스)에게 감사드립니다.
-(void)buttonPressed:(id)sender {
UITableViewCell *clickedCell = (UITableViewCell *)[[sender superview] superview];
NSIndexPath *clickedButtonPath = [self.tableView indexPathForCell:clickedCell];
...
}
태그 패턴을 사용할 수 있습니다.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier = @"identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
[cell autorelelase];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 5, 40, 20)];
[button addTarget:self action:@selector(buttonPressedAction:) forControlEvents:UIControlEventTouchUpInside];
[button setTag:[indexPath row]]; //use the row as the current tag
[cell.contentView addSubview:button];
[button release];
}
UIButton *button = (UIButton *)[cell viewWithTag:[indexPath row]]; //use [indexPath row]
[button setTitle:@"Edit" forState:UIControlStateNormal];
return cell;
}
- (void)buttonPressedAction:(id)sender
{
UIButton *button = (UIButton *)sender;
//button.tag has the row number (you can convert it to indexPath)
}
내가 뭘 빼놓았나요?발신인을 사용하여 버튼을 식별할 수는 없습니다.보낸 사람이 다음과 같은 정보를 제공합니다.
<UIButton: 0x4b95c10; frame = (246 26; 30 30); opaque = NO; tag = 104; layer = <CALayer: 0x4b95be0>>
그런 다음 단추의 속성을 변경하려면 보낸 사람에게 방금 말한 배경 이미지를 말합니다.
[sender setBackgroundImage:[UIImage imageNamed:@"new-image.png"] forState:UIControlStateNormal];
만약 당신이 태그가 필요하다면 ACBurk의 방법은 괜찮습니다.
// how do I know which button sent this message?
// processing button press for this row requires an indexPath.
사실 꽤 간단합니다.
- (void)buttonPressedAction:(id)sender
{
UIButton *button = (UIButton *)sender;
CGPoint rowButtonCenterInTableView = [[rowButton superview] convertPoint:rowButton.center toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:rowButtonCenterInTableView];
MyTableViewItem *rowItem = [self.itemsArray objectAtIndex:indexPath.row];
// Now you're good to go.. do what the intention of the button is, but with
// the context of the "row item" that the button belongs to
[self performFooWithItem:rowItem];
}
나를 위해 잘 일하는 것:p
대상 액션 설정을 조정하려면 메소드에 이벤트 매개 변수를 포함한 다음 해당 이벤트의 터치를 사용하여 터치의 좌표를 확인할 수 있습니다.좌표는 여전히 터치 뷰 경계에서 확인해야 하지만 일부 사용자에게는 더 쉬워 보일 수 있습니다.
nsmutable 어레이를 만들고 [array addObject:yourButton]을 사용하여 해당 어레이에 모든 버튼을 놓습니다.
버튼 누르기 방식으로
-
(void)buttonPressedAction:(id)sender
{
UIButton *button = (UIButton *)sender;
for(int i=0;i<[yourArray count];i++){
if([buton isEqual:[yourArray objectAtIndex:i]]){
//here write wat u need to do
}
}
단추가 표 바닥글에 있을 때('클릭된 셀'을 찾을 수 없음) Cocanuts의 약간 변형이 응답합니다(이것은 이 문제를 해결하는 데 도움이 되었습니다).
-(IBAction) buttonAction:(id)sender;
{
id parent1 = [sender superview]; // UiTableViewCellContentView
id parent2 = [parent1 superview]; // custom cell containing the content view
id parent3 = [parent2 superview]; // UITableView containing the cell
id parent4 = [parent3 superview]; // UIView containing the table
UIView *myContentView = (UIView *)parent1;
UITableViewCell *myTableCell = (UITableViewCell *)parent2;
UITableView *myTable = (UITableView *)parent3;
UIView *mainView = (UIView *)parent4;
CGRect footerViewRect = myTableCell.frame;
CGRect rect3 = [myTable convertRect:footerViewRect toView:mainView];
[cc doSomethingOnScreenAtY:rect3.origin.y];
}
저는 항상 태그를 사용합니다.
하위 분류가 필요합니다.UITableviewCell
거기서 버튼 누르기를 처리합니다.
사용자 지정 셀을 만들고 버튼을 콘센트에 꽂기만 하면 됩니다.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier = @"identifier";
customCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
cell.yourButton.tag = indexPath.Row;
- (void)buttonPressedAction:(id)sender
를 위메를의 id로 합니다.(UIButton *)
sender.tag를 실행하면 어떤 버튼을 누르고 있는지 값을 얻을 수 있습니다.
버튼을 하위 분류하여 필요한 값을 저장하고 프로토콜(ControlWithData)을 만들 수 있습니다.표 보기 셀에 단추를 추가할 때 값을 설정합니다.터치업 이벤트에서 발신인이 프로토콜을 준수하고 데이터를 추출하는지 확인합니다.일반적으로 테이블 뷰 셀에 렌더링되는 실제 객체에 대한 참조를 저장합니다.
SWIFT 2 업데이트
다음은 어떤 버튼을 눌렀는지 확인하고 해당 버튼의 탭에서 다른 ViewController로 데이터를 전송하는 방법입니다.indexPath.row
내 생각에 그것이 대부분의 요점이기 때문입니다!
@IBAction func yourButton(sender: AnyObject) {
var position: CGPoint = sender.convertPoint(CGPointZero, toView: self.tableView)
let indexPath = self.tableView.indexPathForRowAtPoint(position)
let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath!)! as
UITableViewCell
print(indexPath?.row)
print("Tap tap tap tap")
}
ViewController 클래스를 사용하고 tableView를 추가한 사용자의 경우 TableViewController 대신 ViewController를 사용하고 있으므로 테이블View에 액세스하기 위해 수동으로 추가했습니다.
다음은 해당 버튼을 누르고 셀의 데이터를 전달할 때 다른 VC로 데이터를 전달하는 코드입니다. indexPath.row
@IBAction func moreInfo(sender: AnyObject) {
let yourOtherVC = self.storyboard!.instantiateViewControllerWithIdentifier("yourOtherVC") as! YourOtherVCVIewController
var position: CGPoint = sender.convertPoint(CGPointZero, toView: self.tableView)
let indexPath = self.tableView.indexPathForRowAtPoint(position)
let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath!)! as
UITableViewCell
print(indexPath?.row)
print("Button tapped")
yourOtherVC.yourVarName = [self.otherVCVariable[indexPath!.row]]
self.presentViewController(yourNewVC, animated: true, completion: nil)
}
참고로 나는 사용자 지정 셀을 사용하고 있습니다. 이 코드는 나에게 완벽하게 작동합니다.
@IBAction func call(sender: UIButton)
{
var contentView = sender.superview;
var cell = contentView?.superview as EmployeeListCustomCell
if (!(cell.isKindOfClass(EmployeeListCustomCell)))
{
cell = (contentView?.superview)?.superview as EmployeeListCustomCell
}
let phone = cell.lblDescriptionText.text!
//let phone = detailObject!.mobile!
let url:NSURL = NSURL(string:"tel://"+phone)!;
UIApplication.sharedApplication().openURL(url);
}
Chris Schwerdt의 솔루션이지만 Swift에서는 저를 위해 작동했습니다.
@IBAction func rateButtonTapped(sender: UIButton) {
let buttonPosition : CGPoint = sender.convertPoint(CGPointZero, toView: self.ratingTableView)
let indexPath : NSIndexPath = self.ratingTableView.indexPathForRowAtPoint(buttonPosition)!
print(sender.tag)
print(indexPath.row)
}
이 문제는 두 부분으로 나뉩니다.
의인스 의 경로 UITableViewCell
에는 눌린 레스내포함합다니을용된이 있습니다.UIButton
다음과 같은 몇 가지 제안이 있습니다.
업데이트 중
UIButton
의tag
cellForRowAtIndexPath:
의 index path를 하는row
value.가 필요하기 . 업데이트가 필요하기 때문에 좋은 솔루션이 아닙니다.tag
섹션이 둘 이상인 테이블 뷰에서는 연속적으로 작동하지 않습니다.추가
NSIndexPath
및 사용자 지정 셀에 대한 속성UIButton
의tag
cellForRowAtIndexPath:
은 여러 때문에 않습니다.이것은 여러 섹션의 문제를 해결하지만 항상 업데이트가 필요하기 때문에 여전히 좋지 않습니다.UITableView
하고 사용하는 정의indexPathForCell:
인덱스 경로를 가져오는 메서드입니다.더 나은 것 , 조금더나같다니습에서 . 업데이트할 필요가 없습니다.cellForRowAtIndexPath:
메서드이지만 사용자 지정 셀을 만들 때 약한 참조를 설정해야 합니다.셀용을
superView
를 얻는 상위항대참가올속져성를조한.UITableView
사용자 지정 셀에 속성을 추가할 필요가 없으며, 작성/나중에 설정/업데이트할 필요가 없습니다.의 하만셀은지셀은.superView
세부 정보에 달라집니다.iOS 구현 세부 정보에 따라 다릅니다.그래서 그것은 직접 사용할 수 없습니다.
그러나 문제의 셀이 UITableView에 있어야 하기 때문에 간단한 루프를 사용하여 이러한 작업을 수행할 수 있습니다.
UIView* view = self;
while (view && ![view isKindOfClass:UITableView.class])
view = view.superview;
UITableView* parentTableView = (UITableView*)view;
따라서 이러한 제안은 인덱스 경로를 얻기 위한 간단하고 안전한 사용자 지정 셀 방법으로 결합될 수 있습니다.
- (NSIndexPath *)indexPath
{
UIView* view = self;
while (view && ![view isKindOfClass:UITableView.class])
view = view.superview;
return [(UITableView*)view indexPathForCell:self];
}
지금부터 이 방법을 사용하여 다음 중 어떤 것을 탐지할 수 있습니다.UIButton
를 누릅니다.
버튼 누르기 이벤트에 대해 다른 사람에게 알리기
내적으로어것이느부▁which것이ally▁knowing▁intern▁after느어를UIButton
경로가 셀을 이 정보가 " " " 를 뷰"일 것입니다).UITableView
이 이벤트는 와 할 수 .didSelectRowAtIndexPath:
UITableView 대리자 메서드입니다.
이를 위해 두 가지 접근 방식을 사용할 수 있습니다.
위임: 사용자 지정 셀은 다음을 가질 수 있습니다.delegate
프로토콜을 정의할 수 있습니다.delegate
소유물.근데 이거는.delegate
속성을 만들 때 각 사용자 지정 셀에 대해 설정해야 합니다.또는 사용자 정의 셀은 상위 테이블 보기에서 위임 방법을 수행하도록 선택할 수 있습니다.delegate
도 마찬가지야
알림 센터: 사용자 정의 셀은 사용자 정의 알림 이름을 정의하고 에서 제공되는 인덱스 경로 및 상위 테이블 보기 정보와 함께 이 알림을 게시할 수 있습니다.userInfo
각도 설정할 사용자 셀의 하면 됩니다각 셀에 대해 아무것도 설정할 필요가 없으며, 사용자 지정 셀의 알림에 대해 관찰자를 추가하기만 하면 됩니다.
하위 클래스의 솔루션을 사용합니다.UIButton
여기서 공유해야겠다고 생각했어요 스위프트의 코드:
class ButtonWithIndexPath : UIButton {
var indexPath:IndexPath?
}
다음 indexPath의 .cellForRow(at:)
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let returnCell = tableView.dequeueReusableCell(withIdentifier: "cellWithButton", for: indexPath) as! cellWithButton
...
returnCell.button.indexPath = IndexPath
returnCell.button.addTarget(self, action:#selector(cellButtonPressed(_:)), for: .touchUpInside)
return returnCell
}
그래서 버튼의 이벤트에 응답할 때 다음과 같이 사용할 수 있습니다.
func cellButtonPressed(_ sender:UIButton) {
if sender is ButtonWithIndexPath {
let button = sender as! ButtonWithIndexPath
print(button.indexPath)
}
}
언급URL : https://stackoverflow.com/questions/1802707/detecting-which-uibutton-was-pressed-in-a-uitableview
'programing' 카테고리의 다른 글
삭제로 스와이프하고 "추가" 버튼(iOS 7의 메일 앱에서처럼) (0) | 2023.04.27 |
---|---|
참조되지 않은 어셈블리에 유형이 정의되어 있습니다. 원인을 찾는 방법은 무엇입니까? (0) | 2023.04.27 |
Excel에서 NULL 셀 값을 출력합니다. (0) | 2023.04.27 |
'Binding'은 종속성 개체의 종속성 속성에만 설정할 수 있습니다. (0) | 2023.04.27 |
Eclipse에서 디버깅하는 동안 변수가 표시되지 않음 (0) | 2023.04.27 |