IOS 맞춤형 배치 폭포 흐름

11445 단어
폭포류는 전자상거래 응용 전시 상품이 통상적으로 사용하는 방식이다. 예를 들어 그림과 같다.
폭포류의 실현 방식은 보통 다음과 같은 몇 가지가 있다
  • UItableView를 통한 구현(일반적이지 않음)
  • UIScrollView를 통한 구현(많은 작업량)
  • UICollectionView를 통해 구현(일반적으로 사용되는 방식)
  • 1. UICollectionView 기초 1. UICollectionView와 UItableView는 비슷한 점이 많다. 예를 들어
  • 데이터 소스를 통한 데이터 제공
  • 모두 에이전트를 통해 관련 이벤트 수행
  • 모두 셀을 사용자 정의할 수 있고 셀의 재사용과 관련된다
  • UIScrollView에서 상속된 스크롤 효과
  • 2. UICollectionView의 특징
  • UICollection ViewLayout 클래스(일반적으로 UICollection ViewFlow Layout 클래스) 또는 그 하위 클래스의 대상이 있어cell의 레이아웃을 결정해야 한다
  • UICollection View Layout의 하위 클래스를 실현하여 UICollectionView의 굴림 방향과cell의 레이아웃
  • 을 맞춤형으로 설정할 수 있다.
    3. UICollectionViewLayout의 하위 클래스인 UICollectionViewFlowLayout
  • UICollection ViewFlow Layout 즉 흐르는 물 레이아웃
  • 흐르는 물 레이아웃 UICollectionView의 가장 자주 사용하는 레이아웃 방식
  • 2. 사용자 정의 레이아웃 1. 사용자 정의 레이아웃은 UICollectionViewLayout의 하위 클래스를 실현해야 한다. 2. 사용자 정의 레이아웃은 자주 사용하는 방법으로 레이아웃을 초기화한다.
    
    - (void)prepareLayout
    {
      //                 
    }
    

    치수가 변경될 때 레이아웃 업데이트 여부
    
    - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
    {
      //    YES
    }
    

    UICollectionView 레이아웃 요소
    
    - (nullable NSArray<__kindof uicollectionviewlayoutattributes=""> *)layoutAttributesForElementsInRect:(CGRect)rect
    {
      //       rect              
    }
    - (nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
    {
      //     indexPath          
    }
    

    UICollectionView 스크롤 중지 예 오프셋 수정
    
    - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
    {
      //    ,UICollectionView      
    }
    

    3. 예시 1. 효과 실현
    2. 사고방식을 실현한다.
  • UICollectionView를 통한 구현
  • 사용자 정의 레이아웃, 즉 가로 흐름 레이아웃과 원형 일반 레이아웃
  • UICollectionView의 프록시 방법을 통해cell을 눌렀을 때 삭제
  • UIView의 터치 이벤트를 감청하여 컨트롤러의view를 풀 때 레이아웃을 변경
  • 3. 단계별 횡방향 흐름 레이아웃 초기화
    
    - (void)prepareLayout
    {
      [super prepareLayout];
      //      
      self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
      //     
      CGFloat inset = (self.collectionView.frame.size.width - self.itemSize.width) * 0.5;
      self.sectionInset = UIEdgeInsetsMake(0, inset, 0, inset);
    }
    

    치수가 변경될 때 레이아웃 업데이트 지정하기
    
    - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
    {
      return YES;
    }
    

    모든 요소의 레이아웃 속성 설정하기
    
    - (nullable NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
    {
      //  rect            
      NSArray *array = [super layoutAttributesForElementsInRect:rect];
    
      //  UICollectionView   , contentView       
      CGFloat centerX = self.collectionView.contentOffset.x + self.collectionView.frame.size.width * 0.5;
    
      //  rect            ,       UICollectionView      ,     
      for (UICollectionViewLayoutAttributes *attribute in array)
      {
        //         
        CGFloat delta = ABS(attribute.center.x - centerX);
        //      
        CGFloat scale = 1 - delta / self.collectionView.bounds.size.width;
        //      
        attribute.transform = CGAffineTransformMakeScale(scale, scale);
      }
    
      //           
      return [array copy];
    }
    
    

    UICollectionView에서 스크롤을 중지할 오프셋을 중심점으로 설정합니다.
    
    - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
    {
      //          
      CGRect rect;
      rect.origin.x = proposedContentOffset.x;
      rect.origin.y = 0;
      rect.size = self.collectionView.frame.size;
    
      //                   
      NSArray *array = [super layoutAttributesForElementsInRect:rect];
    
      //  UICollectionView   , contentView       
      CGFloat centerX = proposedContentOffset.x + self.collectionView.frame.size.width * 0.5;
    
      //              
      CGFloat minDelta = MAXFLOAT;
      for (UICollectionViewLayoutAttributes *attribute in array)
      {
        CGFloat delta = attribute.center.x - centerX;
        if (ABS(minDelta) > ABS(delta))
        {
          minDelta = delta;
        }
      }
    
      //  UICollectionView    
      proposedContentOffset.x += minDelta;
      return proposedContentOffset;
    }
    
    

    원형 일반 레이아웃 사용자 정의 구성원 속성, 모든 레이아웃 속성 저장
    
    @property (nonatomic, strong) NSMutableArray *attrsArray;
    

    로드 게으름, attrsArray 초기화
    
    - (NSMutableArray *)attrsArray
    {
      if (_attrsArray == nil)
      {
        _attrsArray = [NSMutableArray array];
      }
      return _attrsArray;
    }
    

    레이아웃 초기화
    
    - (void)prepareLayout
    {
      [super prepareLayout];
    
      //          
      [self.attrsArray removeAllObjects];
    
      //       
      NSInteger count = [self.collectionView numberOfItemsInSection:0];
      //       
      for (NSInteger i = 0; i 
     

    indexPath 위치를 레이아웃하는 요소
    
    - (nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(nonnull NSIndexPath *)indexPath
    {
      //       
      NSInteger count = [self.collectionView numberOfItemsInSection:0];
    
      /**      */
      //       
      CGFloat radius = 70;
      //     
      CGFloat oX = self.collectionView.frame.size.width * 0.5;
      CGFloat oY = self.collectionView.frame.size.height * 0.5;
      //  indexPath          
      UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
      //    
      attrs.size = CGSizeMake(50, 50);
      //    
      if (count == 1)
      {
        attrs.center = CGPointMake(oX, oY);
      }
      else
      {
        CGFloat angle = (2 * M_PI / count) * indexPath.item;
        CGFloat centerX = oX + radius * sin(angle);
        CGFloat centerY = oY + radius * cos(angle);
        attrs.center = CGPointMake(centerX, centerY);
      }
      //  indexPath         
      return attrs;
    }
    
    

    레이아웃 지정 영역의 모든 요소
    
    - (nullable NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
    {
      //           
      return self.attrsArray;
    }
    

    xib 사용자 정의cell 설정 구성원 속성으로cell 내부 그림 저장
    /** 이미지 이름*/
    
    @property (nonatomic, copy) NSString *imageName;
    

    cell 초기화
    
    - (void)awakeFromNib
    {
      //  Layer    
      self.imageView.layer.borderColor = [UIColor whiteColor].CGColor;
      self.imageView.layer.borderWidth = 6;
      self.imageView.layer.cornerRadius = 3;
    }

    cell 내 이미지 뷰의 이미지 속성 설정하기
    
    - (void)setImageName:(NSString *)imageName
    {
      _imageName = [imageName copy];
      self.imageView.image = [UIImage imageNamed:imageName];
    }
    

    그림 자원 불러오기 구성원 속성을 통해 모든 그림 이름 저장
    
    /**     */
    @property (nonatomic, strong) NSMutableArray *imageNames;

    불러오기 게으름, 그림 이름 그룹 초기화
    
    - (NSMutableArray *)imageNames
    {
      if (_imageNames == nil)
      {
        NSMutableArray *imageNames = [NSMutableArray array];
        for (NSInteger i = 0; i<20; i++)
        {
          NSString *imageName = [NSString stringWithFormat:@"%zd", i + 1];
          [imageNames addObject:imageName];
        }
        _imageNames = imageNames;
      }
      return _imageNames;
    }
    

    레이아웃을 변경하기 위해 UICollectionView 객체를 멤버 속성으로 저장하는 UICollectionView 만들기
    
    @property (nonatomic, weak) UICollectionView *collectionView;
    

    collectionView 생성 및 설정
    
    - (void)setupCollectionView
    {
      //  frame
      CGFloat collectionViewW = self.view.bounds.size.width;
      CGFloat collectionViewH = 200;
      CGRect frame = CGRectMake(0, 150, collectionViewW, collectionViewH);
    
      //    
      LYPCircleLayout *layout = [[LYPCircleLayout alloc] init];
    
      //  collectionView
      UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:frame collectionViewLayout:layout];
      self.collectionView = collectionView;
    
      //  collectionView       
      collectionView.dataSource = self;
      collectionView.delegate = self;
    
      //  collectionView     view 
      [self.view addSubview:collectionView];
    }
    
    

    UICollectionView의 데이터 소스 등록 방법을 구현cell
    
    /**      */
    static NSString *const ID = @"photo";
    - (void)viewDidLoad
    {
      [super viewDidLoad];
    
      [self setupCollectionView];
    
      //  cell
      [self.collectionView registerNib:[UINib nibWithNibName:NSStringFromClass([LYPPhotoCell class]) bundle:nil] forCellWithReuseIdentifier:ID];
    }
    
    

    요소의 개수 설정하기
    
    - (NSInteger)collectionView:(nonnull UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
    {
      return self.imageNames.count;
    }
    

    각 요소의 속성 설정
    
    - (UICollectionViewCell *)collectionView:(nonnull UICollectionView *)collectionView cellForItemAtIndexPath:(nonnull NSIndexPath *)indexPath
    {
      //             cell,       ,     
      LYPPhotoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];
      //  cell imageName  
      cell.imageName = self.imageNames[indexPath.item];
    
      //  cell
      return cell;
    }
    
    

    요소를 클릭하여 삭제하는 UICollectionView 프록시 구현
    
    - (void)collectionView:(nonnull UICollectionView *)collectionView didSelectItemAtIndexPath:(nonnull NSIndexPath *)indexPath
    {
      //          
      [self.imageNames removeObjectAtIndex:indexPath.item];
      //  collectionView  indexPath     
      [self.collectionView deleteItemsAtIndexPaths:@[indexPath]];
    }
    

    감청 컨트롤러view의 클릭, 레이아웃 바꾸기
    
    - (void)touchesBegan:(nonnull NSSet *)touches withEvent:(nullable UIEvent *)event
    {
      //         
      if ([self.collectionView.collectionViewLayout isKindOfClass:[LYPLineLayout class]])
      {
        //    ,       
        [self.collectionView setCollectionViewLayout:[[LYPCircleLayout alloc] init] animated:YES];
      } else
      {
        //    ,       
        LYPLineLayout *layout = [[LYPLineLayout alloc] init];
        //       ,    ,         
        layout.itemSize = CGSizeMake(130, 130);
        [self.collectionView setCollectionViewLayout:layout animated:YES]; 
      }
    }
    
    

    이상은 본문의 전체 내용입니다. 여러분의 학습에 도움이 되었으면 합니다.

    좋은 웹페이지 즐겨찾기