iOS 带箭头的弹出框

1,221 阅读1分钟
效果

Simulator Screen Shot - iPhone 8 - 2021-08-19 at 16.13.33.png

自定义 PopView
  • PopView.h
@interface PopView : UIView

/*
 @param 被点击的view
 */
-(void)showInView:(UIView *)view;

@end
  • PopView.m
@interface PopView ()

@property (nonatomic, strong) UIView *contentView; // 内容
@property (nonatomic, assign) CGFloat triangleWidth; // 三角形宽度
@property (nonatomic, assign) CGFloat triangleHeight; //  三角形高度
@property (nonatomic, assign) CGPoint startPoint; //  三角形起始位置
@property (nonatomic, assign) CGPoint middlePoint; // 三角形中点位置
@property (nonatomic, assign) CGPoint endPoint; //  三角形结束位置

@end

@implementation PopView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        _triangleWidth = 10.0;
        _triangleHeight = 10.0;
        self.backgroundColor = [UIColor clearColor];
        self.contentView = [[UIView alloc] init];
        self.contentView.backgroundColor = [UIColor orangeColor];
        self.contentView.layer.cornerRadius = 10.0f;
        self.contentView.layer.masksToBounds = YES;
        self.contentView.clipsToBounds = YES;
        [self addSubview:self.contentView];
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    // 获取当前上下文
    CGContextRef context = UIGraphicsGetCurrentContext();
    // 起始位置
    CGContextMoveToPoint(context, self.startPoint.x, self.startPoint.y);
    // 中点位置
    CGContextAddLineToPoint(context, self.middlePoint.x, self.middlePoint.y);
    // 结束位置
    CGContextAddLineToPoint(context, self.endPoint.x, self.endPoint.y);
    CGContextClosePath(context);
    // 设置线的颜色
    [[UIColor orangeColor] setStroke];
    // 设置填充颜色
    [[UIColor orangeColor] setFill];
    // 绘画
    CGContextDrawPath(context, kCGPathFillStroke);
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [self dismiss];
}

#pragma mark - public
- (void)showInView:(UIView *)view
{
    UIWindow *window = [UIApplication sharedApplication].windows.firstObject;
    [window addSubview:self];
    [self mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.right.bottom.equalTo(window);
    }];
    // 将传入的 view 进行坐标系转换,转换成相对于 Windows 的坐标
    CGRect convertFrame = [view convertRect:view.bounds toView:window];
    // 获取到传入的 view 在 Windows 上面的 centerX,作为三角形箭头的 centerX
    CGFloat centerX = convertFrame.size.width * 0.5 + convertFrame.origin.x;
    // 获取到 contentView 的 y 值
//    CGFloat y = convertFrame.origin.y - contentSize.height;
    // 设置 contentView frame
    [self.contentView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.bottom.equalTo(view.mas_top).offset(-10.0);
        make.centerX.equalTo(view);
        make.width.mas_equalTo(100.0);
        make.height.mas_equalTo(140.0);
    }];
    // 设置三角形的坐标
    self.middlePoint = CGPointMake(centerX, convertFrame.origin.y);
    self.startPoint = CGPointMake(centerX - self.triangleWidth * 0.5, self.middlePoint.y - self.triangleHeight);
    self.endPoint = CGPointMake(centerX + self.triangleWidth * 0.5, self.middlePoint.y - self.triangleHeight);
}

#pragma mark - private
- (void)dismiss
{
    [self removeFromSuperview];
}
@end