[ios] UITableViewCell의 accessoryView에 대한 사용자 정의 이미지 사용 및 UITableViewDelegate에 응답

셀에 대해 동일한 것을 포함하여 사용자 정의 UIUIViewViewCell을 사용하고 accessoryView있습니다. accessoryView에 대한 내 설정은 다음과 같은 방식으로 발생합니다.

UIImage *accessoryImage = [UIImage imageNamed:@"accessoryDisclosure.png"];
UIImageView *accImageView = [[UIImageView alloc] initWithImage:accessoryImage];
accImageView.userInteractionEnabled = YES;
[accImageView setFrame:CGRectMake(0, 0, 28.0, 28.0)];
self.accessoryView = accImageView;
[accImageView release];

또한 셀이 초기화 될 때 initWithFrame:reuseIdentifier:다음을 사용하여 다음 속성을 설정했습니다.

self.userInteractionEnabled = YES;

불행히도 내 UITableViewDelegate에서 내 tableView:accessoryButtonTappedForRowWithIndexPath:메소드 (10 회 반복 시도)가 트리거되지 않습니다. 델리게이트가 올바르게 연결되었습니다.

무엇을 놓칠 수 있습니까?

모두 감사합니다.



답변

슬프게도 미리 정의 된 유형 중 하나를 사용할 때 제공된 내부 버튼 유형을 누르지 않으면 해당 메소드가 호출되지 않습니다. 직접 사용하려면 액세서리를 버튼 또는 다른 UIControl 서브 클래스로 만들어야합니다 ( -buttonWithType:UIButtonTypeCustomUIImageView를 사용하는 대신 버튼 이미지를 사용 하고 설정 하는 버튼을 권장합니다 ).

다음은 Outpost에서 사용하는 몇 가지 사항입니다. 표준 위젯을 약간 커스터마이징하여 (청록색과 일치하도록) UITableViewController 중개 하위 클래스를 사용하여 다른 모든 테이블보기에서 사용할 유틸리티 코드를 보유했습니다 (이제 하위 클래스). OPTableViewController).

먼저이 함수는 사용자 정의 그래픽을 사용하여 새로운 세부 정보 공개 버튼을 반환합니다.

- (UIButton *) makeDetailDisclosureButton
{
    UIButton * button = [UIButton outpostDetailDisclosureButton];

[button addTarget: self
               action: @selector(accessoryButtonTapped:withEvent:)
     forControlEvents: UIControlEventTouchUpInside];

    return ( button );
}

버튼은 완료되면이 루틴을 호출 한 다음 액세서리 버튼에 표준 UITableViewDelegate 루틴을 제공합니다.

- (void) accessoryButtonTapped: (UIControl *) button withEvent: (UIEvent *) event
{
    NSIndexPath * indexPath = [self.tableView indexPathForRowAtPoint: [[[event touchesForView: button] anyObject] locationInView: self.tableView]];
    if ( indexPath == nil )
        return;

    [self.tableView.delegate tableView: self.tableView accessoryButtonTappedForRowWithIndexPath: indexPath];
}

이 기능은 버튼으로 제공된 이벤트에서 터치 테이블 뷰의 위치를 ​​가져 와서 해당 시점에서 행의 인덱스 경로에 대한 테이블 뷰를 요청하여 행을 찾습니다.


답변

이 웹 사이트가 매우 유용하다는 것을 알았습니다
.iphone에서 uitableview에 대한 사용자 정의 액세서리보기

요컨대, 이것을 다음에서 사용하십시오 cellForRowAtIndexPath::

UIImage *image = (checked) ? [UIImage imageNamed:@"checked.png"] : [UIImage imageNamed:@"unchecked.png"];

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect frame = CGRectMake(0.0, 0.0, image.size.width, image.size.height);
button.frame = frame;
[button setBackgroundImage:image forState:UIControlStateNormal];

[button addTarget:self action:@selector(checkButtonTapped:event:)  forControlEvents:UIControlEventTouchUpInside];
button.backgroundColor = [UIColor clearColor];
cell.accessoryView = button;

그런 다음이 방법을 구현하십시오.

- (void)checkButtonTapped:(id)sender event:(id)event
{
    NSSet *touches = [event allTouches];
    UITouch *touch = [touches anyObject];
    CGPoint currentTouchPosition = [touch locationInView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint: currentTouchPosition];

    if (indexPath != nil)
    {
        [self tableView: self.tableView accessoryButtonTappedForRowWithIndexPath: indexPath];
    }
}


답변

내 접근 방식은 UITableViewCell하위 클래스 를 만들고 그 UITableViewDelegate안에 일반적인 메소드를 호출하는 논리를 캡슐화하는 것입니다.

// CustomTableViewCell.h
@interface CustomTableViewCell : UITableViewCell

- (id)initForIdentifier:(NSString *)reuseIdentifier;

@end

// CustomTableViewCell.m
@implementation CustomTableViewCell

- (id)initForIdentifier:(NSString *)reuseIdentifier;
{
    // the subclass specifies style itself
    self = [super initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:reuseIdentifier];
    if (self) {
        // get the button elsewhere
        UIButton *accBtn = [ViewFactory createTableViewCellDisclosureButton];
        [accBtn addTarget: self
                   action: @selector(accessoryButtonTapped:withEvent:)
         forControlEvents: UIControlEventTouchUpInside];
        self.accessoryView = accBtn;
    }
    return self;
}

#pragma mark - private

- (void)accessoryButtonTapped:(UIControl *)button withEvent:(UIEvent *)event
{
    UITableViewCell *cell = (UITableViewCell*)button.superview;
    UITableView *tableView = (UITableView*)cell.superview;
    NSIndexPath *indexPath = [tableView indexPathForCell:cell];
    [tableView.delegate tableView:tableView accessoryButtonTappedForRowWithIndexPath:indexPath];
}

@end


답변

위의 Jim Dovey의 답변에 대한 확장 :

UITableView와 함께 UISearchBarController를 사용할 때주의하십시오. 이 경우 대신 확인 self.searchDisplayController.active하고 사용 하고 싶습니다 . 그렇지 않으면 searchDisplayController가 활성화되어있을 때, 특히 검색 결과가 스크롤 될 때 예기치 않은 결과가 발생합니다.self.searchDisplayController.searchResultsTableViewself.tableView

예를 들면 다음과 같습니다.

- (void) accessoryButtonTapped:(UIControl *)button withEvent:(UIEvent *)event
{
    UITableView* tableView = self.tableView;
    if(self.searchDisplayController.active)
        tableView = self.searchDisplayController.searchResultsTableView;

    NSIndexPath * indexPath = [tableView indexPathForRowAtPoint:[[[event touchesForView:button] anyObject] locationInView:tableView]];
    if(indexPath)
       [tableView.delegate tableView:tableView accessoryButtonTappedForRowWithIndexPath:indexPath];
}


답변

  1. 버튼 태그에 대한 매크로를 정의하십시오.

    #define AccessoryViewTagSinceValue 100000 // (AccessoryViewTagSinceValue * sections + rows) must be LE NSIntegerMax
  2. 셀을 만들 때 만들기 버튼을 누르고 cell.accessoryView를 설정하십시오.

    UIButton *accessoryButton = [UIButton buttonWithType:UIButtonTypeContactAdd];
    accessoryButton.frame = CGRectMake(0, 0, 30, 30);
    [accessoryButton addTarget:self action:@selector(accessoryButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
    cell.accessoryView = accessoryButton;
  3. UITableViewDataSource 메소드 -tableView : cellForRowAtIndexPath에서 indexPath로 cell.accessoryView.tag를 설정하십시오.

    cell.accessoryView.tag = indexPath.section * AccessoryViewTagSinceValue + indexPath.row;
  4. 버튼의 이벤트 핸들러

    - (void) accessoryButtonTapped:(UIButton *)button {
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:button.tag % AccessoryViewTagSinceValue
                                                    inSection:button.tag / AccessoryViewTagSinceValue];
    
        [self.tableView.delegate tableView:self.tableView accessoryButtonTappedForRowWithIndexPath:indexPath];
    }
  5. UITableViewDelegate 메소드 구현

    - (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
        // do sth.
    }

답변

버튼을 누르면 UITableViewCell 서브 클래스 내에서 다음 메소드를 호출 할 수 있습니다.

 -(void)buttonTapped{
     // perform an UI updates for cell

     // grab the table view and notify it using the delegate
     UITableView *tableView = (UITableView *)self.superview;
     [tableView.delegate tableView:tableView accessoryButtonTappedForRowWithIndexPath:[tableView indexPathForCell:self]];

 }


답변

yanchenko 접근 방식으로 다음을 추가해야했습니다. [accBtn setFrame:CGRectMake(0, 0, 20, 20)];

xib 파일을 사용하여 tableCell을 사용자 정의하는 경우 initWithStyle : reuseIdentifier :가 호출되지 않습니다.

대신 재정의하십시오.

-(void)awakeFromNib
{
//Put your code here 

[super awakeFromNib];

}