UI 테이블 보기에서 누른 UI 버튼 감지
나는 있습니다UITableView5와 함께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의tagcellForRowAtIndexPath:의 index path를 하는rowvalue.가 필요하기 . 업데이트가 필요하기 때문에 좋은 솔루션이 아닙니다.tag섹션이 둘 이상인 테이블 뷰에서는 연속적으로 작동하지 않습니다.추가
NSIndexPath및 사용자 지정 셀에 대한 속성UIButton의tagcellForRowAtIndexPath:은 여러 때문에 않습니다.이것은 여러 섹션의 문제를 해결하지만 항상 업데이트가 필요하기 때문에 여전히 좋지 않습니다.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 |