UIPopoverPresentationController 弹出 UIViewController 包裹的 UICollectionView

前两天有一个需要点击一个按钮控件弹出 UIPopoverPresentationController 的需求,并且在 弹出的 Controller  中需要显示一个 UICollectionView ,Cell 中又一张图片,一个Label,数据需要充数据库中读取。

我们首先要做的事情就是 创建一个用于 UIPopoverPresentationController 弹出的 Controller , 

下面是 h 文件  

//
//  PDPeopleCollectionView.h
//  PeopleView
//
//  Created by Will Han on 12/23/15.
//  Copyright © 2015 GearPart. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "Entities.h"

@interface PDPeopleView : UIViewController

@property(copy, nonatomic) NSArray *titles;
@property(copy, nonatomic) NSArray *groupOne;   /**< DataEntity */
@property(copy, nonatomic) NSArray *groupTwo;   /**< DataEntity */

@end

我们在该 h 文件中设置了三个数组,titles 用于显示  UICollectionView  中 Section 的 Header,因为可能有多个Section  所以用到了数组, groupOne 和   groupTwo 是为了存放 Section1 和 Section2 中cell 中的Label 中的数据(这里先放两个Section,以后可以根据需求自行增加或者减少)


下面是 m 文件

//
//  PDPeopleCollectionView.m
//
//  Created by Jack on 12/23/15.
//  Copyright © 2015 GearPart. All rights reserved.
//

#import "PDPeopleView.h"

#pragma mark - header

#import <UIKit/UIKit.h>
#define kCollectionHeaderViewIdentifier @"aHeader"

@interface PDPeopleCollectionHeaderView : UICollectionReusableView

@property(strong, nonatomic) UILabel *headerLabel;

@end

@implementation PDPeopleCollectionHeaderView

@synthesize headerLabel;

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = kBackgroundColor_RGB255;
        headerLabel = [[UILabel alloc] init];
        headerLabel.translatesAutoresizingMaskIntoConstraints = NO;
        headerLabel.contentMode = UIViewContentModeBottomLeft;
        headerLabel.font = TheSystemBoldFont(15);
        headerLabel.textColor = kFontColor_R102G119GB136;
        [self addSubview:headerLabel];
        AddConstraints(self, @[ @"H:|-20-[headerLabel]-20-|", @"V:|-(>=0)-[headerLabel]-5-|" ], nil, NSDictionaryOfVariableBindings(headerLabel));
    }
    return self;
}

@end

#pragma mark - cell

#define kCellIndentifier @"aCell"

@interface PeopleViewCell : UICollectionViewCell

@property(strong, nonatomic) UIImageView *iv;
@property(strong, nonatomic) UILabel *lb;

@end

@implementation PeopleViewCell

@synthesize iv;
@synthesize lb;

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        iv = [[UIImageView alloc] init];
        iv.translatesAutoresizingMaskIntoConstraints = NO;
        iv.layer.cornerRadius = 45.f / 2.f;
#if DEBUG
        iv.layer.borderWidth = 1.f;
        iv.layer.borderColor = [[UIColor orangeColor] CGColor];
        iv.contentMode = UIViewContentModeScaleToFill;
#endif
        iv.clipsToBounds = YES;

        lb = [[UILabel alloc] init];
        lb.translatesAutoresizingMaskIntoConstraints = NO;
        lb.font = TheSystemFont(14);
        lb.textColor = kFontColor_R102G119GB136;
        lb.lineBreakMode = NSLineBreakByTruncatingTail;
        lb.numberOfLines = 0;

        [self addSubview:iv];
        [self addSubview:lb];
        AddCenterYConstraints(self, iv, lb, nil);
        AddHeightConstraints(self, 45, iv, nil);

        AddConstraints(self, @[ @"H:|[iv(45)]-5-[lb(100)]|", @"V:|[lb]|" ], nil, NSDictionaryOfVariableBindings(iv, lb));
    }
    return self;
}

@end

#pragma mark - controller

@interface PDPeopleView () <UICollectionViewDataSource, UICollectionViewDelegate>

@property(strong, nonatomic) UICollectionView *cw;

@end

@implementation PDPeopleView

@synthesize titles;
@synthesize groupOne;
@synthesize groupTwo;
@synthesize cw;

- (void)viewDidLoad {
    [super viewDidLoad];

    UICollectionViewFlowLayout *flowLayout = [UICollectionViewFlowLayout instance];
    flowLayout.itemSize = CGSizeMake(150, 57);
    flowLayout.minimumInteritemSpacing = 10.0f;
    flowLayout.minimumLineSpacing = 0.0f;

    if ([flowLayout respondsToSelector:@selector(setSectionHeadersPinToVisibleBounds:)]) {
        flowLayout.sectionHeadersPinToVisibleBounds = YES;
    }
    if ([flowLayout respondsToSelector:@selector(setSectionFootersPinToVisibleBounds:)]) {
        flowLayout.sectionFootersPinToVisibleBounds = YES;
    }

    self.cw = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:flowLayout];
    self.cw.translatesAutoresizingMaskIntoConstraints = NO;
    self.cw.dataSource = self;
    self.cw.delegate = self;
    self.cw.backgroundColor = [UIColor whiteColor];
    [self.cw registerClass:[PeopleViewCell class] forCellWithReuseIdentifier:kCellIndentifier];
    [self.cw registerClass:[PDPeopleCollectionHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:kCollectionHeaderViewIdentifier];

    [self.view addSubview:self.cw];

    AddConstraints(self.view, @[ @"H:|[cw]|", @"V:|[cw]|" ], nil, @{ @"cw" : cw });
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    CGSize size;
    
    CGFloat v1 = (groupOne.count / 2  + groupOne.count % 2) * 57 + 45 + 20;
    CGFloat v2 = v1 + (groupTwo.count / 2 + groupTwo.count % 2) * 57 + 45;
    if (groupTwo.count == 0) {
        if  (v1 > 338) {
            v1 = 338;
        }
        size = (groupOne.count == 1) ? CGSizeMake(190, v1) : CGSizeMake(350, v1);
    } else {
        if  (v2 > 338) {
            v2 = 338;
        }
        size = (groupTwo.count == 1 && groupOne.count == 1) ? CGSizeMake(190, v2) : CGSizeMake(350, v2);
    }
    [self setPreferredContentSize:size];

    UICollectionViewFlowLayout *layout = (UICollectionViewFlowLayout *)cw.collectionViewLayout;
    size.height = 45.f;
    layout.headerReferenceSize = size;
}

#pragma mark - data source

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    if (groupTwo.count == 0) {
        return 1;
    }
    return 2;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    if (section == 0) {
        return groupOne.count;
    }
    return groupTwo.count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    PeopleViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kCellIndentifier forIndexPath:indexPath];

    UserEntity *user;
    if (indexPath.section == 0) {
        user = groupOne[indexPath.row];
        cell.lb.text = user.DisplayName;
        cell.iv.image = [UIImage imageNamed:@"idle"];
    } else {
        //        user = groupTwo[indexPath.row];
        //        cell.lb.text = user.DisplayName;
        //        cell.iv.image = [UIImage imageNamed:@"document"];
        cell.lb.text = groupTwo[indexPath.row];
        cell.iv.image = [UIImage imageNamed:@"idle"];
    }

    return cell;
}

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {

    if ([UICollectionElementKindSectionHeader isEqualToString:kind]) {
        PDPeopleCollectionHeaderView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:kCollectionHeaderViewIdentifier forIndexPath:indexPath];
        headerView.headerLabel.text = (indexPath.section == 0 ? titles[0] : titles[1]);
        return headerView;
    }
    return nil;
}

#pragma mark - delegate

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    return UIEdgeInsetsMake(0, 20, (section == 1 || groupTwo.count == 0) ? 20 : 0, 20);
}
@end

在上面的 m 文件中 定义并规划了 section 的Header ,  UICollectionViewCell 和  在UIViewController 中实现整体布局以及UICollectionView 的代理,这个 m 文件是有点大,不过滤清了,思路并不复杂。。

这样我们为 UIPopoverPresentationController 准备的 弹出的 Controller 就完成了,下面我们用 UIPopoverPresentationController 来弹出它。

if (self.selectAction.AssignedToList.count == 0) {
        return;
    }
    PDPeopleView *peopleView = [PDPeopleView instance];
    peopleView.groupOne = self.selectAction.AssignedToList;
    peopleView.titles = @[kAssignee];
    peopleView.modalPresentationStyle = UIModalPresentationPopover;
    UIPopoverPresentationController *popover = peopleView.popoverPresentationController;
    popover.backgroundColor = kBackgroundColor_RGB255;
    popover.sourceView = button.titleLabel;
    popover.sourceRect = button.titleLabel.bounds;
    popover.permittedArrowDirections = UIPopoverArrowDirectionAny;
    [[UIWindow TopViewController] presentViewController:peopleView animated:YES completion:nil];

上面的那段代码就是 UIPopoverPresentationController 弹出的  Controller 的过程了,需要注意的是 最好写成是  popover.sourceView = button.titleLabel; 而不要写成  popover.sourceView = button;  因为我们要指向的是文字文字,所以如果写成  popover.sourceView = button如果 Button 中还有包含其他控件,箭头有可能会偏离文字。。

效果如下图 :

单列数据:

双排数据:



这样就完成了需求,有问题欢迎留言交流~~


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值