修复UIPopoverController已弃用的iOS 9自定义类问题

时间:2017-03-17 12:19:39

标签: ios objective-c ios9 uipopovercontroller deprecation-warning

我有一个项目,我已经创建了一个自定义UIPopoverController类,并在我的项目的几个部分中使用,但现在从iOS 9 UIPopoverController不推荐使用。我想知道是否有任何简单的方法可以修改我现有的popoverclass,以便我使用它的其他部分保持不变或具有最小的更改。下面是我创建的自定义类。

**myCustomPopover.h file**

#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>

@interface myCustomPopover : UIPopoverController

@property (readonly) UIColor *tintColor;

- (id)initWithContentViewController:(UIViewController *)viewController andTintColor: (UIColor *)tintColor;

@end


**mycustomPopover.m file**

#import "myCustomPopover.h"

#pragma mark - Internal Constants
CGFloat const contentInset = 5.0;
CGFloat const capInset = 25.0;
CGFloat const arrowHeight = 25.0;
CGFloat const arrowBase = 25.0;

@interface myCustomPopoverControllerBackgroundView : UIPopoverBackgroundView
{
    UIImageView *borderImageView;
    UIImageView *arrowImageView;
}

+ (UIColor *)currentTintColor;
+ (void)setCurrentTintColor: (UIColor *)tintColor;

@end

@implementation myCustomPopoverControllerBackgroundView

#pragma mark - Internal Class Variables
static UIColor *currentTintColor;

#pragma mark - Initializers
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame: frame];
    if (!self)
        return nil;

    UIGraphicsBeginImageContext(CGSizeMake(60, 60));

    UIBezierPath *borderPath = [UIBezierPath bezierPathWithRoundedRect: CGRectMake(0, 0, 60, 60)
                                                          cornerRadius: 8];




    [currentTintColor setFill];

    [borderPath fill];

    UIImage *borderImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    UIEdgeInsets capInsets = UIEdgeInsetsMake(capInset, capInset, capInset, capInset);
    borderImageView = [[UIImageView alloc] initWithImage: [borderImage resizableImageWithCapInsets: capInsets]];

    UIGraphicsBeginImageContext(CGSizeMake(25, 25));

    UIBezierPath *arrowPath = [UIBezierPath bezierPath];
    [arrowPath moveToPoint: CGPointMake(12.5, 0)];
    [arrowPath addLineToPoint: CGPointMake(25, 25)];
    [arrowPath addLineToPoint: CGPointMake(0, 25)];
    [arrowPath addLineToPoint: CGPointMake(12.5, 0)];

    UIGraphicsBeginImageContext(CGSizeMake(24, 15));
    self.opaque = NO;


    [currentTintColor setFill];
    [arrowPath fill];

    UIImage *arrowImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    arrowImageView = [[UIImageView alloc] initWithImage: arrowImage];

    arrowImageView.layer.shadowColor = [UIColor blackColor].CGColor;
    arrowImageView.layer.shadowOpacity = .4;
    arrowImageView.layer.shadowRadius = 2;
    arrowImageView.layer.shadowOffset = CGSizeMake(0, 1);
    arrowImageView.layer.masksToBounds = YES;

    [self addSubview: borderImageView];
    [self addSubview: arrowImageView];

    return self;
}

#pragma mark - Class Accessors and Mutators
+ (UIColor *)currentTintColor
{
    return currentTintColor;
}

+ (void)setCurrentTintColor:(UIColor *)tintColor
{
    currentTintColor = tintColor;
}

#pragma mark - Class Handlers
+ (UIEdgeInsets)contentViewInsets
{
    return UIEdgeInsetsMake(contentInset, contentInset, contentInset, contentInset);
}

+ (CGFloat)arrowHeight
{
    return arrowHeight;
}

+ (CGFloat)arrowBase
{
    return arrowBase;
}

-(void) setArrowOffset:(CGFloat)_arrowOffset
{
    arrowOffset = _arrowOffset;
    [self setNeedsLayout];
}

-(void) setArrowDirection:(UIPopoverArrowDirection)_arrowDirection
{
    arrowDirection = _arrowDirection;
    [self setNeedsLayout];
}

#pragma mark - View Handlers
@synthesize arrowOffset;
@synthesize arrowDirection;

-(void)layoutSubviews
{
    [super layoutSubviews];

    CGFloat popoverImageOriginX = 0;
    CGFloat popoverImageOriginY = 0;

    CGFloat popoverImageWidth = self.bounds.size.width;
    CGFloat popoverImageHeight = self.bounds.size.height;

    CGFloat arrowImageOriginX = 0;
    CGFloat arrowImageOriginY = 0;

    CGFloat arrowImageWidth = arrowBase;
    CGFloat arrowImageHeight = arrowHeight ;
    CGAffineTransform rotation = CGAffineTransformIdentity;

    CGFloat factor=0.0;

    // Radius value you used to make rounded corners in your popover background image
    CGFloat cornerRadius = 8;


    switch (self.arrowDirection) {

        case UIPopoverArrowDirectionUp:

            popoverImageOriginY = arrowHeight - factor;
            popoverImageHeight = self.bounds.size.height - arrowHeight;

            // Calculating arrow x position using arrow offset, arrow width and popover width
            arrowImageOriginX = roundf((self.bounds.size.width - arrowBase) / 2 + self.arrowOffset);

            // If arrow image exceeds rounded corner arrow image x postion is adjusted
            if (arrowImageOriginX + arrowBase > self.bounds.size.width - cornerRadius)
            {
                arrowImageOriginX -= cornerRadius;
            }

            if (arrowImageOriginX < cornerRadius)
            {
                arrowImageOriginX += cornerRadius;
            }



            break;

        case UIPopoverArrowDirectionDown:

            popoverImageHeight = self.bounds.size.height - arrowHeight + factor;

            arrowImageOriginX = roundf((self.bounds.size.width - arrowBase) / 2 + self.arrowOffset);

            if (arrowImageOriginX + arrowBase > self.bounds.size.width - cornerRadius)
            {
                arrowImageOriginX -= cornerRadius;
            }

            if (arrowImageOriginX < cornerRadius)
            {
                arrowImageOriginX += cornerRadius;
            }

            arrowImageOriginY = popoverImageHeight - factor;
            rotation = CGAffineTransformMakeRotation(M_PI);


            break;

        case UIPopoverArrowDirectionLeft:

            popoverImageOriginX = arrowHeight - factor;
            popoverImageWidth = self.bounds.size.width - arrowHeight;

            arrowImageOriginY = roundf((self.bounds.size.height - arrowBase) / 2 + self.arrowOffset);

            if (arrowImageOriginY + arrowBase > self.bounds.size.height - cornerRadius)
            {
                arrowImageOriginY -= cornerRadius;
            }

            if (arrowImageOriginY < cornerRadius)
            {
                arrowImageOriginY += cornerRadius;
            }

            arrowImageWidth = arrowHeight;
            arrowImageHeight = arrowBase;

          rotation = CGAffineTransformMakeRotation(-M_PI_2);

            break;

        case UIPopoverArrowDirectionRight:

            popoverImageWidth = self.bounds.size.width - arrowHeight + factor;

            arrowImageOriginX = popoverImageWidth - factor;
            arrowImageOriginY = roundf((self.bounds.size.height - arrowBase) / 2 + self.arrowOffset);

            if (arrowImageOriginY + arrowBase > self.bounds.size.height - cornerRadius)
            {
                arrowImageOriginY -= cornerRadius;
            }

            if (arrowImageOriginY < cornerRadius)
            {
                arrowImageOriginY += cornerRadius;
            }

            arrowImageWidth = arrowHeight;
            arrowImageHeight = arrowBase;
            rotation = CGAffineTransformMakeRotation(M_PI_2);

            break;

        default:

            // For popovers without arrows
            popoverImageHeight = self.bounds.size.height - arrowHeight + factor;

            break;
    }

    borderImageView.frame = CGRectMake(popoverImageOriginX, popoverImageOriginY, popoverImageWidth, popoverImageHeight);
    arrowImageView.frame = CGRectMake(arrowImageOriginX, arrowImageOriginY, arrowImageWidth, arrowImageHeight);
    [arrowImageView setTransform: rotation];
}


@end

@implementation myCustomPopoverController

#pragma mark - Properties
@synthesize tintColor;

#pragma mark - Initializers
- (id)initWithContentViewController:(UIViewController *)viewController
{
    self = [self initWithContentViewController: viewController
                                  andTintColor: [UIColor blackColor]];
    return self;
}

- (id)initWithContentViewController:(UIViewController *)viewController andTintColor:(UIColor *)aTintColor
{
    self = [super initWithContentViewController: viewController];
    if (!self)
        return nil;


    [super setPopoverBackgroundViewClass: [myCustomPopoverControllerBackgroundView class]];
    currentTintColor = aTintColor;
      tintColor = aTintColor;

    return self;
}

#pragma mark - Overriders
- (void)setPopoverBackgroundViewClass:(Class)popoverBackgroundViewClass {}


@end

我尝试将子类更改为UIPopoverPresentationController,但有一些错误,例如initWithContentViewController没有接口。这是接近的正确方法吗?

2 个答案:

答案 0 :(得分:0)

您必须将视图控制器的modalPresentationStyle用于UIModalPresentationPopover。

答案 1 :(得分:0)

没有必要担心。我们有fppopover

需要uiviewcontroller,然后显示像popover一样。 无需定制自己。