programing

Reference from UITableViewCell to parent UITableView?

telecom 2023. 10. 22. 19:25
반응형

Reference from UITableViewCell to parent UITableView?

소유권에 접근할 수 있는 방법이 있나요?UITableView안에서UITableViewCell?

저장 aweak테이블 참조셀에서 설정한 보기-tableView:cellForRowAtIndexPath:당신의 테이블의 dataSource.

이것은 의지하는 것보다 낫습니다.self.superview항상 테이블이 되는 것 보기는 깨지기 쉽습니다.애플이 어떻게 뷰 계층을 재구성할 수 있는지 누가 알겠습니까?UITableView미래에.

특정 UITableView 계층에 의존하지 않는 보다 나은 방법이 있습니다.다음과 같은 경우 향후 iOS 버전과 함께 사용할 수 있습니다.UITableView클래스 이름을 완전히 변경하지는 않습니다.가능성이 극히 낮을 뿐만 아니라, 만일 가능하다면 당신은 당신의 코드를 수정해야 할 것입니다.

아래의 카테고리를 가져오면 다음과 같이 참조할 수 있습니다.[myCell parentTableView]

@implementation UIView (FindUITableView)

-(UITableView *) parentTableView {
    // iterate up the view hierarchy to find the table containing this cell/view
    UIView *aView = self.superview;
    while(aView != nil) {
        if([aView isKindOfClass:[UITableView class]]) {
            return (UITableView *)aView;
        }
        aView = aView.superview;
    }
    return nil; // this view is not within a tableView
}

@end


// To use it, just import the category and invoke it like so:
UITableView *myTable = [myTableCell parentTableView];

// It can also be used from any subview within a cell, from example
// if you have a UILabel within your cell, you can also do:
UITableView *myTable = [myCellLabel parentTableView];

// NOTE:
// If you invoke this on a cell that is not part of a UITableView yet
// (i.e., on a cell that you just created with [[MyCell alloc] init]),
// then you will obviously get nil in return. You need to invoke this on cells/subviews
// that are already part of a UITableView.


갱신하다
댓글에는 약한 참조를 유지하는 것이 더 나은 접근법인지에 대한 논의가 있습니다.그것은 당신의 상황에 따라 다릅니다.뷰 계층을 횡단하면 대상 UIView가 식별될 때까지 루프를 수행할 때 약간의 런타임 페널티가 발생합니다.당신의 견해는 얼마나 깊은가요?반면, 모든 셀에 대해 참조를 유지하는 것은 메모리 패널티를 최소화하는 것이며(결국 참조가 약하다는 것은 포인터임), 일반적으로 필요하지 않은 곳에 개체 관계를 추가하는 것은 여러 가지 이유로 잘못된 OO 설계 관행으로 간주되므로 피해야 합니다(아래 주석의 자세한 내용 참조).

더 중요한 것은 셀 내부에 테이블 참조를 보관하는 것은 코드 복잡성을 가중시키고 오류를 초래할 수 있기 때문입니다.UITableViewCells재사용이 가능합니다.는 우연이 아닙니다.UIKit를 포함하지 않습니다.cell.parentTable소유물.자신을 정의할 경우 코드를 추가하여 관리해야 하며, 효율적으로 정의하지 못할 경우 메모리 누수가 발생할 수 있습니다(즉, 셀의 수명이 테이블 수명을 초과함).

일반적으로 사용자가 셀(단일 셀에 대해 실행)과 상호 작용할 때 위의 범주를 사용하고 테이블 배치 시에는 사용하지 않기 때문입니다.[tableView:cellForRowAtIndexPath:](모든 눈에 보이는 셀에 대해 execute), 런타임 비용은 미미해야 합니다.

Xcode 7 beta, Swift 2.0

This works fine for me, in my opinion it has nothing to do with the hierarchy or whatever. I had no trouble with this approach so far. I've used this for many async callbacks (ex. when an API request is done).

TableViewCell 클래스

class ItemCell: UITableViewCell {

    var updateCallback : ((updateList: Bool)-> Void)? //add this extra var

    @IBAction func btnDelete_Click(sender: AnyObject) {
        let localStorage = LocalStorage()
        if let description = lblItemDescription.text
        {
            //I delete it here, but could be done at other class as well.
            localStorage.DeleteItem(description) 
        }
        updateCallback?(updateList : true)

    }
}

DataSource 및 Delegate를 구현하는 테이블 뷰 클래스 내부

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell: ItemCell = self.ItemTableView.dequeueReusableCellWithIdentifier("ItemCell") as! ItemCell!
    cell.updateCallback = UpdateCallback //add this extra line
    cell.lblItemDescription?.text = self.SomeList[indexPath.row].Description
    return cell
}

func UpdateCallback(updateTable : Bool) //add this extra method
{
    licensePlatesList = localStorage.LoadNotificationPlates()
    LicenseTableView.reloadData()
}

물론 당신은 어떤 변수라도 넣을 수 있습니다.updateCallback기능을 변경합니다.tableView따라서.

누군가가 사용하기에 절약할 수 있는지 알려주길 원할 수도 있지만, 확실히 하기 위해서 말입니다.

테이블 뷰 셀을 구성할 때 UITableView에 참조를 다시 추가해야 합니다.

하지만 당신이 정말로 원하는 것은 당신의 UITableViewController에 대한 참조입니다.셀을 만들 때 셀의 대리인으로 설정하여 테이블 뷰에 전달합니다.

작업을 배선하는 경우 다른 방법은 테이블 보기 컨트롤러를 파일 소유자로 하여 IB에 셀을 구축한 다음 셀의 버튼을 테이블 보기 컨트롤러의 작업에 배선하는 것입니다.loadNibNamed와 함께 셀 xib을 로드할 때, 보기 컨트롤러를 소유자로 전달하면 버튼 작업이 테이블 보기 컨트롤러에 다시 연결됩니다.

UITableViewCells에 대한 사용자 정의 클래스가 있는 경우 셀의 헤더에 id 유형 변수를 추가하고 변수를 합성할 수 있습니다.셀을 로드할 때 변수를 설정한 후에는 테이블 뷰 또는 기타 상위 뷰로 원하는 작업을 별도의 번거로움이나 오버헤드 없이 자유롭게 수행할 수 있습니다.

세포.h

 // interface
 id root;

 // propery 
 @property (nonatomic, retain) id root;

감방의

@synthe 크기 뿌리,

tableview controller.m

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  // blah blah, traditional cell declaration
  // but before return cell;
  cell.root = tableView;
}

이제 루트 변수를 사용하여 셀 내에서 테이블뷰 메소드를 호출할 수 있습니다.(예: [root reloadData]))

아, 플래시 프로그래밍의 좋은 시절로 돌아가게 해주네요.

다른 답변의 두 가지 방법은 (A) 테이블에 대한 참조를 저장하거나 (B) 화면 위로 걸어가는 것입니다.

저는 항상 (A)를 모델 객체에 사용하고 (B)를 테이블 셀에 사용합니다.

UITableViewCell을 처리하는 경우, AFAIK에 UITableView가 가까이 있거나(테이블 위임 메서드에 있다고 가정) 뷰 계층에 있는 보이는 셀을 처리하고 있어야 합니다.그렇지 않으면 잘못하고 있을 수도 있습니다. ("잘 할 수도 있다"는 점에 유의하시기 바랍니다.

셀은 자유롭게 재사용되며, 만약 보이지 않는 셀이 있다면, 셀이 존재하는 유일한 실제 이유는 iOS UITableView 성능 최적화 때문입니다(화면 밖으로 이동할 때 더 느린 iOS 버전이 셀을 릴리스하고 셀을 잠금 해제할 수 있음) 또는 셀에 대한 특정 참조가 있기 때문입니다.이것이 테이블 셀에 테이블뷰 인스턴스 메서드가 부여되지 않은 이유일 것입니다.

따라서 (B) 지금까지의 모든 iOS와 미래의 모든 OS에 대해 올바른 결과를 제공한 후에 그들이 어떻게 작동하는지 근본적으로 바꿀 때까지 말입니다.

일반화 가능한 코드를 반복해서 쓰는 것을 피하기 위해 다음과 같은 방법을(를)

+ (id)enclosingViewOfView:(UIView *)view withClass:(Class)returnKindOfClass {
  while (view&&![view isKindOfClass:returnKindOfClass]) view=view.superview;
  return(view);
}

그리고 편리한 방법:

+ (UITableView *)tableForCell:(UITableViewCell *)cell {
  return([self enclosingViewOfView:cell.superview withClass:UITableView.class]);
}

(또는 원하는 경우 범주)

그건 그렇고, 그 정도 크기의 반복 횟수가 20회 정도인 루프가 당신의 앱 성능에 미치는 영향이 걱정된다면..하지 마.

모델들

셀에 표시되는 모델 개체에 대해 말하는 경우 해당 모델은 셀의 모델이 표시될 수 있는 테이블을 찾거나 변경을 트리거하는 데 사용될 수 있는 상위 모델에 대해 알 수 있습니다.이는 (A)와 같지만 향후 iOS 업데이트를 통해 취약성이 줄어듭니다(예: 언젠가 테이블 뷰별 재사용 식별자가 아닌 재사용 식별자별로 UITableViewCell 재사용 캐시가 존재하게 될 수 있습니다. 그 날 취약한 참조 방법을 사용하는 모든 구현이 중단됩니다).

모델이 표시되는 모든 곳에 변경 사항이 전파되므로(예: 앱의 다른 곳에 있는 다른 UIViewController, logging 등) 이 모델 메서드는 셀에 표시된 데이터의 변경 사항(예: 모델 변경 사항)에 사용됩니다.

방법은 테이블 뷰 작업에 사용될 것이며, 셀이 테이블의 하위 뷰가 아닌 경우에는 항상 좋지 않은 아이디어일 수 있습니다(비록 당신의 코드이긴 하지만 미친 듯이).

어느 쪽이든, iOS를 업데이트할 때 겉보기에는 더 깨끗한 코드가 작동한다고 가정하기보다는 단위 테스트를 사용합니다.

UITableView *tv = (UITableView *) self.superview.superview;
UITableViewController *vc = (UITableViewController *) tv.dataSource;

언급URL : https://stackoverflow.com/questions/1110482/reference-from-uitableviewcell-to-parent-uitableview

반응형