>

기본적으로 컬렉션 뷰는 셀을 삽입하는 동안 컨텐츠 오프셋을 유지합니다. 반면에 현재 표시되는 셀 위에 셀을 삽입하여 이전 메시지를로드 할 때 Messages.app와 같이 화면 상단 가장자리 위에 표시되도록하고 싶습니다. 누구든지 그것을 달성하는 방법을 알고 있습니까?


  • 답변 # 1

    이것이 내가 사용하는 기술이다. 다른 사람들이 화면 깜박임과 같은 이상한 부작용을 일으키는 것을 발견했습니다.

       CGFloat bottomOffset = self.collectionView.contentSize.height - self.collectionView.contentOffset.y;
        [CATransaction begin];
        [CATransaction setDisableActions:YES];
        [self.collectionView performBatchUpdates:^{
            [self.collectionView insertItemsAtIndexPaths:indexPaths];
        } completion:^(BOOL finished) {
            self.collectionView.contentOffset = CGPointMake(0, self.collectionView.contentSize.height - bottomOffset);
        }];
        [CATransaction commit];
    
    

  • 답변 # 2

    제임스 마틴의 환상적인 버전이 스위프트 2로 변환되었습니다 :

    let amount = 5 // change this to the amount of items to add
    let section = 0 // change this to your needs, too
    let contentHeight = self.collectionView!.contentSize.height
    let offsetY = self.collectionView!.contentOffset.y
    let bottomOffset = contentHeight - offsetY
    CATransaction.begin()
    CATransaction.setDisableActions(true)
    self.collectionView!.performBatchUpdates({
        var indexPaths = [NSIndexPath]()
        for i in 0..<amount {
            let index = 0 + i
            indexPaths.append(NSIndexPath(forItem: index, inSection: section))
        }
        if indexPaths.count > 0 {
            self.collectionView!.insertItemsAtIndexPaths(indexPaths)
        }
        }, completion: {
            finished in
            print("completed loading of new stuff, animating")
            self.collectionView!.contentOffset = CGPointMake(0, self.collectionView!.contentSize.height - bottomOffset)
            CATransaction.commit()
    })
    
    

  • 답변 # 3

    내 접근 방식은 하위 클래스 흐름 레이아웃을 활용합니다. 이는 뷰 컨트롤러에서 스크롤/레이아웃 코드를 해킹 할 필요가 없음을 의미합니다. 아이디어는 셀을 맨 위에 삽입한다는 것을 알 때마다 사용자 정의 속성을 설정하면 다음 레이아웃 업데이트에서 셀을 맨 위에 삽입하고 업데이트 전에 내용 크기를 기억한다는 플래그입니다. 그런 다음 PreparingLayout ()을 재정의하고 원하는 콘텐츠 오프셋을 설정합니다. 다음과 같이 보입니다 :

    변수 정의

    private var isInsertingCellsToTop: Bool = false
    private var contentSizeWhenInsertingToTop: CGSize?
    
    

    재정의 prepareLayout()  슈퍼 전화 후

    if isInsertingCellsToTop == true {
        if let collectionView = collectionView, oldContentSize = contentSizeWhenInsertingToTop {
            let newContentSize = collectionViewContentSize()
            let contentOffsetY = collectionView.contentOffset.y + (newContentSize.height - oldContentSize.height)
            let newOffset = CGPointMake(collectionView.contentOffset.x, contentOffsetY)
            collectionView.setContentOffset(newOffset, animated: false)
    }
        contentSizeWhenInsertingToTop = nil
        isInsertingMessagesToTop = false
    }
    
    

  • 답변 # 4

    이 작업은 두 줄의 코드로 수행되었지만 (UITableView에 있지만) 동일한 방식으로 수행 할 수 있다고 생각합니다.

    테이블 뷰를 180도 회전했습니다.

    그런 다음 각 테이블 뷰 셀을 180도 회전했습니다.

    이것은 표준 상단에서 하단 테이블로 처리 할 수 ​​있지만 하단은 상단과 같이 취급되었습니다.

  • 답변 # 5

    Fogmeister의 답변에 코드를 추가하면 가장 깨끗한 접근 방식은 ( 거꾸로 뒤집다)  상단이 아니라 하단에 고정되어있는 스크롤보기가 있습니다. 이것은 또한 UICollectionView 에서 작동합니다 Fogmeister가 지적한대로

    UITableView
    
    

    Swift에서 :

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        self.collectionView.transform = CGAffineTransformMake(1, 0, 0, -1, 0, 0);
    }
    
    

    이것은 셀을 거꾸로 표시하는 부작용이 있으므로 셀도 뒤집어 야합니다. 그래서 우리는 trasform ( override func viewDidLoad() { super.viewDidLoad() collectionView.transform = CGAffineTransformMake(1, 0, 0, -1, 0, 0) } )을 옮깁니다. ) 이렇게 :

    cell.transform = collectionView.transform
    
    

    Swift에서 :

    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    {
        UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
        cell.transform = collectionView.transform;
        return cell;
    }
    
    
    마지막으로,이 디자인으로 개발할 때 기억해야 할 것은 func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { var cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! UICollectionViewCell cell.transform = collectionView.transform return cell } 라는 것입니다.  델리게이트의 매개 변수는 반대로됩니다. 그래서 NSIndexPath   indexPath.row == 0 의 맨 아래에있는 행입니다  일반적으로 상단에 있습니다.

    이 기술은 많은 오픈 소스 프로젝트에서 슬랙이 관리하는 인기있는 SlackTextViewController (https://github.com/slackhq/SlackTextViewController)를 포함하여 설명 된 동작을 생성하기 위해 사용됩니다

    Fogmeister의 환상적인 답변에 코드 컨텍스트를 추가하려고 생각했습니다!

    collectionView

  • 이전 Google은 v3 표준 아이콘/그림자 이름을 매핑합니다 (v2의 G_DEFAULT_ICON과 동일)
  • 다음 c++ - Clang이 창에서 작동하도록하기