programing

Storyboard 프로토타입 셀(Xcode 6, iOS 8 SDK)에서 UICollectionViewCell contentView 프레임의 자동 크기 조정 문제는 iOS 7에서만 발생합니다.

mailnote 2023. 4. 21. 21:11
반응형

Storyboard 프로토타입 셀(Xcode 6, iOS 8 SDK)에서 UICollectionViewCell contentView 프레임의 자동 크기 조정 문제는 iOS 7에서만 발생합니다.

Xcode 6 베타 3, iOS 8 SDK를 사용하고 있습니다. Swift를 사용하여 타겟 iOS 7.0을 구축하십시오.아래의 스크린샷으로 나의 문제를 차근차근 참조해 주세요.

Storyboard에 UICollectionView가 있습니다.1 프로토타입 UICollectionViewCell에는 중앙에 라벨이 1개 포함되어 있습니다(자동 크기 조정 규칙은 없습니다).보라색 배경은 Cell에 의해 런타임에 생성된 contentView를 마킹하는 것이었습니다.이 뷰는 최종적으로 UICollectionViewLayoutDelegate를 기반으로 크기가 적절히 조정되지만 iOS7에서는 크기가 조정되지 않습니다. Xcode6을 사용하고 있으며 문제가 발생하는 것은 iOS7뿐입니다.

iOS 8에서 앱을 만들 때, 모든 것이 정상입니다.

주의: 퍼플은 콘텐츠 표시, 파란색은 모서리가 둥근 UIButton입니다.

http://i.stack.imgur.com/uDNDY.png

그러나 iOS 7에서는 셀 내의 모든 서브뷰가 갑자기 (0,0,50,50) 프레임으로 축소되어 더 이상 자동 크기 조정 규칙을 준수하지 않습니다.

http://i.stack.imgur.com/lOZH9.png

iOS 8 SDK나 Swift, 또는 Xcode의 버그라고 생각됩니다.


업데이트 1: 이 문제는 공식 Xcode 6.0.1에도 존재합니다.최적의 회피책은 KoCMoHaBTa가 아래 셀의 cellForItem에 프레임을 설정하는 것과 같습니다(단, 셀의 서브클래스를 지정해야 합니다).이것은 iOS 8 SDK와 iOS 7의 호환성이 없는 것으로 판명되었습니다(아래 애플에서 인용한 에코택스의 답변을 확인해 주세요).

업데이트 2: 코드를 cellForItem의 선두에 붙여넣으면 문제가 없습니다.

/** Xcode 6 on iOS 7 hot fix **/
cell.contentView.frame = cell.bounds;
cell.contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
/** End of Xcode 6 on iOS 7 hot fix **/

contentView가 파손되었습니다.awake From Nib에서도 수정할 수 있습니다.

ObjC:

- (void)awakeFromNib {

    [super awakeFromNib];

    self.contentView.frame = self.bounds;
    self.contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
}

Swift3:

override func awakeFromNib() {
    super.awakeFromNib()

    self.contentView.frame = self.bounds
    self.contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
}

동일한 문제가 발생하여 Apple DTS에 도움을 요청했습니다.답변은 다음과 같습니다.

iOS 7에서는 셀의 콘텐츠 뷰가 마스크 자동 재설정을 통해 크기를 조정했습니다.iOS 8에서는 이것이 변경되어 셀은 자동 크기 조정 마스크 사용을 중지하고 layoutSubviews의 콘텐츠 뷰 크기를 조정하기 시작했습니다.nib가 iOS 8에서 인코딩된 후 iOS 7에서 디코딩되면 자동 크기 조정 마스크나 크기를 조정할 수 있는 다른 수단이 없는 컨텐츠 보기를 얻을 수 있습니다.따라서 셀의 프레임을 변경할 경우 내용 보기가 따라오지 않습니다.

iOS 7로 다시 배포하는 앱은 콘텐츠 보기 자체의 크기를 조정하거나 마스크 자동 크기 조정 또는 제약 조건을 추가하는 방식으로 이 문제를 해결해야 합니다.

XCode 6의 버그가 아니라 iOS 8 SDK와 iOS 7 SDK의 호환성이 없기 때문에 Xcode 6으로 업그레이드하면 자동으로 iOS 8 SDK가 사용되기 때문입니다.

앞서 언급했듯이 Daniel Plamann이 설명한 회피책은 나에게 효과가 있습니다.Igor Palaguta와 KoCMoHaBTa가 설명한 것은 단순해 보이고 Apple DTS의 답변도 일리가 있을 것 같기 때문에 나중에 시험해 보겠습니다.

같은 문제가 발생했기 때문에 다음 Xcode 버전에서는 Apple이 수정해 주셨으면 합니다.그 사이에 회피책을 쓰고 있습니다.의 마마 my에서는UICollectionViewCell layoutSubviews가 와 다를 보기collectionViewCellsyslog.syslog.syslogs.

- (void)layoutSubviews
{
  [super layoutSubviews];

  BOOL contentViewIsAutoresized = CGSizeEqualToSize(self.frame.size, self.contentView.frame.size);

  if( !contentViewIsAutoresized) {
    CGRect contentViewFrame = self.contentView.frame;
    contentViewFrame.size = self.frame.size;
    self.contentView.frame = contentViewFrame;
  }
}

해결 하고 contentView의 마스크 를 자동 조정하는 입니다.-collectionView:cellForItemAtIndexPath:음음음같 뭇매하다

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

     static NSString *cellID = @"CellID";

     UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellID forIndexPath:indexPath];

     // Set contentView's frame and autoresizingMask
     cell.contentView.frame = cell.bounds;
     cell.contentView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin |UIViewAutoresizingFlexibleTopMargin |UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin;

     // Your custom code goes here

     return cell;
}

자동 크기 조정 마스크는 제약 조건으로 변환되므로 자동 레이아웃에서도 작동합니다.

Xcode 6.0.1에서는 UICollectionViewCell용 컨텐츠 뷰가 iOS7 디바이스용으로 파손되어 있습니다.또한 UICollectionViewCell과 wakeFromNib 또는 init 메서드의 contentView에 적절한 제약을 추가하여 수정할 수도 있습니다.

        UIView *cellContentView = self.contentView;
        cellContentView.translatesAutoresizingMaskIntoConstraints = NO;

        [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[cellContentView]|"
                                                                     options:0
                                                                     metrics:0
                                                                       views:NSDictionaryOfVariableBindings(cellContentView)]];
        [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[cellContentView]|"
                                                                     options:0
                                                                     metrics:0
                                                                       views:NSDictionaryOfVariableBindings(cellContentView)]];

이것은 Xcode 6 GM에 Xcode가 xib 파일을 nib 형식으로 컴파일하는 버그가 있기 때문에 다른 회피책이 없으면 올바르게 동작하지 않습니다.Xcode가 실행 시와는 무관하고 Xcode와 관련된 것이라고 100% 확신할 수는 없지만, 저는 매우 자신 있습니다.이것을 나타내는 방법은 다음과 같습니다.

  1. 빌드+Xcode 5.1에서 응용 프로그램을 실행합니다.
  2. 시뮬레이터 애플리케이션의 디렉토리로 이동하여 문제가 있는 xib의 컴파일된 .nib 파일을 복사합니다.
  3. 빌드+Xcode 6 GM에서 응용 프로그램을 실행합니다.
  4. 애플리케이션을 정지합니다.
  5. 새로 빌드된 응용 프로그램의 시뮬레이터 폴더에 있는 .nib 파일을 Xcode 5.1을 사용하여 만든 .nib 파일로 바꿉니다.
  6. Xcode가 아닌 시뮬레이터에서 앱을 다시 실행합니다.
  7. 이 .nib에서 로드된 셀은 예상대로 작동합니다.

나는 이 질문을 읽는 모든 사람들이 애플에 레이더를 제출하기를 바란다.이것은 큰 문제이며, 최종 Xcode 릴리즈 전에 대처해야 합니다.

편집: 에코택스의 투고에 비추어 iOS 8과 iOS 7의 구축에 있어서의 동작의 차이가 확인되고 있습니다만, 버그가 아닙니다.iOS 7을 기반으로 구축한 결과, 이 작업을 수행하기 위해 필요한 컨텐츠 뷰에 자동 크기 조정 마스크가 추가되었고, 애플은 이를 더 이상 추가하지 않았습니다.

이 포스트 워크의 해답은, 왜 동작하는지를 이해하지 못했습니다.

우선, 다음의 2개의 「규칙」이 있습니다.

  1. 「 」 「 」 、 「 」 ( 「 : : 」[UIView new] ), 。translatesAutoresizingMaskIntoConstraints로 설정되어 있다.YES
  2. 네이블로 되어 있는 빌더에서 에는 AutoLayout .translatesAutoresizingMaskIntoConstraintsNO

두 번째 규칙은 구속조건을 정의하지 않은 최상위 보기에는 적용되지 않습니다(예: 내용 보기).

볼 때 에는 셀이 .contentView노출되어 있습니다.하고 있는 은 아니다.contentView Apple™입니다.

를 자세히 하는지 하십시오.contentView츠키다

<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">

표시됩니다(「」에 해 주세요).translatesAutoresizingMaskIntoConstraints="NO"

<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="NaT-qJ-npL" userLabel="myCustomLabel">

contentViewtranslatesAutoresizingMaskIntoConstraintsNO게다가 @ecotax가 말한 것처럼 레이아웃의 정의도 결여되어 있습니다.

''에 contentView마스크는 않습니다.<autoresizingMask key="autoresizingMask"/>

결론은 두 가지입니다.

  1. contentView translatesAutoresizingMaskIntoConstraints로 설정되어 있다.YES.
  2. contentView레이아웃에 대한 정의가 없습니다.

이것에 의해, 지금까지 이야기되어 온 2개의 솔루션이 실현됩니다.

는 수동으로 할 수 .awakeFromNib:

self.contentView.frame = cell.bounds;
self.contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

'보다 낫다'를 도 있어요.contentView translatesAutoresizingMaskIntoConstraints로로 합니다.NOawakeFromNib해 주세요.- (void)updateConstraints.

이것은 Swift 버전의 @Igor의 답변으로 받아들여지고 있으며, 당신의 친절한 답변 상대에게 감사드립니다.

First Goto yourUICollectionViewCell다음 코드를 클래스 내에 있는 그대로 서브클래스로 붙여 넣습니다.

override func awakeFromNib() {
    super.awakeFromNib()
    self.contentView.frame = self.bounds
    self.contentView.autoresizingMask = [.FlexibleHeight, .FlexibleWidth]
}

참고로 Xcode 7.3.1과 Swift 2.3을 사용하고 있습니다.솔루션은 완벽하게 작동하는 iOS 9.3에서 테스트되었습니다.

고마워요, 도움이 됐으면 좋겠네요.

빠르게 다음 코드를 컬렉션 뷰 셀 하위 클래스에 배치합니다.

override var bounds: CGRect {
  didSet {
    // Fix autolayout constraints broken in Xcode 6 GM + iOS 7.1
    self.contentView.frame = bounds
  }
}

에도 문제가 있음을 알게 되었습니다.contentView사이징을 실행할 수 있습니다.사이클이 매우 늦게 배치되는 경향이 있으며, 이로 인해 일시적인 제약 충돌이 발생할 수 있습니다.이를 해결하기 위해 다음과 같은 방법을 카테고리에 추가했다.UICollectionViewCell:

- (void)fixupContentView
{
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 80100
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
    if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1) {
        self.contentView.frame = self.bounds;
        self.contentView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin |UIViewAutoresizingFlexibleTopMargin |UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin;
    } else {
        [self layoutIfNeeded];
    }
#endif
#endif
}

이 메서드는 셀의 큐를 해제한 후에 호출해야 합니다.

이 작업을 수정했습니다.

override func layoutSubviews() {
   contentView.superview?.frame = bounds
   super.layoutSubviews()
}

참조: 여기

해당 컬렉션 뷰 셀의 니브에 있는 "서브뷰 자동 조정" 확인란을 선택해야 합니다.iOS 8과 iOS 7 모두 정상적으로 작동합니다.

언급URL : https://stackoverflow.com/questions/24750158/autoresizing-issue-of-uicollectionviewcell-contentviews-frame-in-storyboard-pro

반응형