UIPopoverPresentationController 背景が透明で奥のレイヤーが見えるポップオーバーにする
目的
下記のようなアプリがある場合にポップオーバーを表示するとこうなりますよね。
このように緑色のUIView
を透かしたい場合があるのですが、
うっすら見えますけども、透明ではないですよね。
手順
❶UIPopoverBackgroundView
のサブクラスを追加する。
❷UIPopoverPresentationController
のプロパティ.popoverBackgroundViewClass
に❶のクラスを指定する。
##実装(Objective-C)
### ViewController.m
#import "ViewController.h"
@interface ViewController ()<UIPopoverPresentationControllerDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
// ボタン押下後に呼び出される。
- (IBAction)tapButton:(id)sender {
TableViewController *vc = [[TableViewController alloc]init];
[self presentPopOverWithViewController:vc sourceView:sender];
}
- (void)presentPopOverWithViewController:(UIViewController *)viewController sourceView:(UIView *)sourceView
{
viewController.modalPresentationStyle = UIModalPresentationPopover;
viewController.preferredContentSize = CGSizeMake(300.0, 44.0 * 5);
UIPopoverPresentationController *presentationController = viewController.popoverPresentationController;
//下記記述が重要
presentationController.popoverBackgroundViewClass = [PopoverBackgroundView class];
presentationController.delegate = self;
presentationController.permittedArrowDirections = UIPopoverArrowDirectionUp;
presentationController.sourceView = sourceView;
presentationController.sourceRect = sourceView.bounds;
[self presentViewController:viewController animated:YES completion:NULL];
}
//iPhoneでの描画に大きく関係するのでしっかり追加しておく
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller
{
return UIModalPresentationNone;
}
@end
PopoverBackgroundView.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface PopoverBackgroundView : UIPopoverBackgroundView
@end
NS_ASSUME_NONNULL_END
@end
###PopoverBackgroundView.m
// PopoverBackgroundView.m
#import "PopoverBackgroundView.h"
@interface PopoverBackgroundView ()
{
CGFloat _arrowOffset;
UIPopoverArrowDirection _arrowDirection;
}
@end
@implementation PopoverBackgroundView
+ (CGFloat)arrowHeight
{
return 0.0f;
}
+ (UIEdgeInsets)contentViewInsets
{
return UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, 0.0f);
}
- (UIPopoverArrowDirection)arrowDirection
{
return _arrowDirection;
}
- (void)setArrowDirection:(UIPopoverArrowDirection)arrowDirection
{
_arrowDirection = arrowDirection;
}
- (CGFloat)arrowOffset
{
return _arrowOffset;
}
- (void)setArrowOffset:(CGFloat)arrowOffset
{
_arrowOffset = arrowOffset;
}
- (void)layoutSubviews
{
[super layoutSubviews];
self.layer.shadowOpacity = 0.0f;
}
@end
変更後は下記スクリーンショットのようになります。
<img width="375" alt="Simulator Screen Shot - iPhone 8 - 2020-03-01 at 17.15.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551622/b573a3eb-f1f4-16fd-9c24-d56bc34a35b7.png">
##実際に開発現場でどのように使われてくるか
デザイナーさんが**「ポップオーバーを押下したレイヤーの上に透明に重なるように」という意図を持って、**透過がある画像ファイルを作成してくださった際に、ただポップオーバー上に表示するだけではレイヤーの上に透明に重なるように
は実装できません。
なのでポップオーバーの背景自体
を透明色を適用する必要があります。
謝辞
下記記事を引用しております。
Xcode11、またUIPopoverPresentationController
と明記していなかったのでこちらの記事を出させていただきました。
UIPopoverControllerの背景色を透明にする
本記事含め他の記事は「長時間1人で悩んで不安やストレスフルな方を解決したい」という一心で更新しております。少額でも構いませんのでサポートしていただけますと記事更新のモチベーションになりますので、御援助いただけますと助かります。
Discussion