Ios 如何使此弹出扩展更通用,以应用于任何视图?
我已将在github上找到的弹出式扩展编辑为以下内容Ios 如何使此弹出扩展更通用,以应用于任何视图?,ios,swift,Ios,Swift,我已将在github上找到的弹出式扩展编辑为以下内容 import UIKit class Home: UIViewController { override func viewDidLoad() { self.PopUpInit() super.viewDidLoad() } var overlayView: UIView! var alertView: UIView! var animator: UIDyna
import UIKit
class Home: UIViewController
{
override func viewDidLoad()
{
self.PopUpInit()
super.viewDidLoad()
}
var overlayView: UIView!
var alertView: UIView!
var animator: UIDynamicAnimator!
}
PopUpExtension.swift:
import UIKit
extension (Home)
{
//Call this method in view did load
func PopUpInit()
{
createOverlay()
createAlert()
}
func createOverlay()
{
let p = CGRectMake(self.view!.frame.origin.x, self.view!.frame.origin.y, self.view!.bounds.size.width, self.view!.bounds.size.height)
overlayView = UIView(frame: p)
overlayView.backgroundColor = UIColor.grayColor()
overlayView.alpha = 0.0
self.view!.addSubview(overlayView)
}
func createAlert()
{
let alertWidth: CGFloat = UIScreen.mainScreen().bounds.width
let alertHeight: CGFloat = UIScreen.mainScreen().bounds.height
let alertViewFrame: CGRect = CGRectMake(0,0, alertWidth, alertHeight)
alertView = UIView(frame: alertViewFrame)
alertView.center = self.view.center
alertView.backgroundColor = UIColor.clearColor()
alertView.alpha = 0.0
let button = UIButton(type: UIButtonType.System)
button.setTitle("Cancel", forState: UIControlState.Normal)
button.setTitleColor(UIColor.redColor(), forState: UIControlState.Normal)
button.backgroundColor = UIColor.clearColor()
button.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height)
button.addTarget(self, action: "dismissAlert", forControlEvents: UIControlEvents.TouchUpInside)
button.center.x = alertView.center.x
let button1 = UIButton(type: UIButtonType.RoundedRect)
button1.setTitle("Send", forState: UIControlState.Normal)
button1.backgroundColor = UIColor.greenColor()
button1.frame = CGRectMake(100, 100, 80.0, 80.0)
button1.addTarget(self, action: "Button1", forControlEvents: UIControlEvents.TouchUpInside)
button1.center.x = alertView.center.x
let button2 = UIButton(type: UIButtonType.RoundedRect)
button2.setTitle("Send", forState: UIControlState.Normal)
button2.backgroundColor = UIColor.greenColor()
button2.frame = CGRectMake(100, 200, 80.0, 80.0)
button2.addTarget(self, action: "Button2", forControlEvents: UIControlEvents.TouchUpInside)
button2.center.x = alertView.center.x
let button3 = UIButton(type: UIButtonType.RoundedRect)
button3.setTitle("Send", forState: UIControlState.Normal)
button3.backgroundColor = UIColor.greenColor()
button3.frame = CGRectMake(100, 300, 80.0, 80.0)
button3.addTarget(self, action: "Button3", forControlEvents: UIControlEvents.TouchUpInside)
button3.center.x = alertView.center.x
alertView.addSubview(button)
alertView.addSubview(button1)
alertView.addSubview(button2)
alertView.addSubview(button3)
self.view!.addSubview(alertView)
}
func showAlert()
{
if (alertView == nil)
{
createAlert()
}
UIView.animateWithDuration(0.3)
{
self.overlayView.alpha = 0.5
self.alertView.alpha = 1.0
}
}
func dismissAlert()
{
UIView.animateWithDuration(0.15, animations:
{
self.overlayView.alpha = 0.0
self.alertView.alpha = 0.0
}, completion:
{
(value: Bool) in
self.alertView.removeFromSuperview()
self.alertView = nil
})
}
func Button1()
{
print("button1")
}
func Button2()
{
print("button2")
}
func Button3()
{
print("button3")
}
}
现在在Home.swift视图控制器中,我只需执行以下操作
import UIKit
class Home: UIViewController
{
override func viewDidLoad()
{
self.PopUpInit()
super.viewDidLoad()
}
var overlayView: UIView!
var alertView: UIView!
var animator: UIDynamicAnimator!
}
问题是:
如何将这个扩展转换成一个可以在任何需要的地方使用的类,不仅仅是Home.swift,我还希望避免将这些定义为使用这个弹出窗口的所有类
var overlayView: UIView!
var alertView: UIView!
var animator: UIDynamicAnimator!
你能告诉我做这件事的最佳方法吗
谢谢。让它更通用的诀窍是让它更面向协议。使用
协议
您可以利用默认实现
来定义一致性类型
需要什么样,并使用扩展
来实现方法
素材:
import UIKit
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
弹出列表:
import UIKit
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
let vc = UIViewController()
let window = UIWindow(frame: UIScreen.mainScreen().bounds)
window.makeKeyAndVisible()
window.rootViewController = vc
vc.view.backgroundColor = UIColor.greenColor()
XCPlaygroundPage.currentPage.liveView = vc.view
let pop = PopUp()
pop.showAlert(animated: true)
这将是您的主要协议
。任何具有视图
变量的内容都可以设置为可弹出
@objc protocol PopUpAble : class {
var view : UIView! { get set }
func button1()
func button2()
func button3()
func alertWillDismiss() -> Bool
func alertDidDismiss()
func dismissAlert()
}
标识类型:
import UIKit
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
let vc = UIViewController()
let window = UIWindow(frame: UIScreen.mainScreen().bounds)
window.makeKeyAndVisible()
window.rootViewController = vc
vc.view.backgroundColor = UIColor.greenColor()
XCPlaygroundPage.currentPage.liveView = vc.view
let pop = PopUp()
pop.showAlert(animated: true)
这些是协议
和一致性类
,能够区分警报视图
和覆盖视图
,而无需将它们分配给属性
。更少的样板代码->更好
protocol AlertType : class {}
protocol OverlayType : class {}
class AlertView : UIView, AlertType {}
class OverlayView : UIView, OverlayType {}
实现:
import UIKit
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
let vc = UIViewController()
let window = UIWindow(frame: UIScreen.mainScreen().bounds)
window.makeKeyAndVisible()
window.rootViewController = vc
vc.view.backgroundColor = UIColor.greenColor()
XCPlaygroundPage.currentPage.liveView = vc.view
let pop = PopUp()
pop.showAlert(animated: true)
这是与您之前相同的函数集合
,只是修改为使用弹出表
协议
中提供的功能
函数现在搜索现有的匹配类型或创建create…
- 没有更多的设置功能,不需要
- 可选动画
- 设置显示/隐藏之前/之后的视图顺序
extension PopUpAble {
func createOverlay() -> UIView {
if let overlay = (view.subviews.filter { $0 is OverlayType }).first {
return overlay
}
let p = CGRectMake(self.view!.frame.origin.x, self.view!.frame.origin.y, self.view!.bounds.size.width, self.view!.bounds.size.height)
let overlayView = OverlayView(frame: p)
overlayView.backgroundColor = UIColor.grayColor()
overlayView.alpha = 0.0
view!.insertSubview(overlayView, atIndex: 0)
return overlayView
}
func createAlert() -> UIView {
if let alert = (view.subviews.filter { $0 is AlertType }).first {
return alert
}
let alertWidth: CGFloat = UIScreen.mainScreen().bounds.width
let alertHeight: CGFloat = UIScreen.mainScreen().bounds.height
let alertViewFrame: CGRect = CGRectMake(0,0, alertWidth, alertHeight)
let alertView = AlertView(frame: alertViewFrame)
alertView.center = self.view.center
alertView.backgroundColor = UIColor.clearColor()
alertView.alpha = 0.0
let button = UIButton(type: UIButtonType.System)
button.setTitle("Cancel", forState: UIControlState.Normal)
button.setTitleColor(UIColor.redColor(), forState: UIControlState.Normal)
button.backgroundColor = UIColor.clearColor()
button.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height)
button.addTarget(self, action: #selector(Self.dismissAlert), forControlEvents: UIControlEvents.TouchUpInside)
button.center.x = alertView.center.x
let button1 = UIButton(type: UIButtonType.RoundedRect)
button1.setTitle("Send", forState: UIControlState.Normal)
button1.backgroundColor = UIColor.greenColor()
button1.frame = CGRectMake(100, 100, 80.0, 80.0)
button1.addTarget(self, action: #selector(Self.button1), forControlEvents: UIControlEvents.TouchUpInside)
button1.center.x = alertView.center.x
let button2 = UIButton(type: UIButtonType.RoundedRect)
button2.setTitle("Send", forState: UIControlState.Normal)
button2.backgroundColor = UIColor.greenColor()
button2.frame = CGRectMake(100, 200, 80.0, 80.0)
button2.addTarget(self, action: #selector(Self.button2), forControlEvents: UIControlEvents.TouchUpInside)
button2.center.x = alertView.center.x
let button3 = UIButton(type: UIButtonType.RoundedRect)
button3.setTitle("Send", forState: UIControlState.Normal)
button3.backgroundColor = UIColor.greenColor()
button3.frame = CGRectMake(100, 300, 80.0, 80.0)
button3.addTarget(self, action: #selector(Self.button3), forControlEvents: UIControlEvents.TouchUpInside)
button3.center.x = alertView.center.x
alertView.addSubview(button)
alertView.addSubview(button1)
alertView.addSubview(button2)
alertView.addSubview(button3)
view!.insertSubview(alertView, atIndex: 1)
return alertView
}
func showAlert(animated animated:Bool = true) {
func show(alert:UIView,overlay:UIView) {
if animated {
UIView.animateWithDuration(0.3) {
overlay.alpha = 0.5
alert.alpha = 1.0
}
} else {
overlay.alpha = 0.5
alert.alpha = 1.0
}
}
let overlay = createOverlay()
let alert = createAlert()
view.bringSubviewToFront(overlay)
view.bringSubviewToFront(alert)
show(alert, overlay: overlay)
}
func hideAlert(animated animated:Bool = true) {
guard alertWillDismiss() else {
return
}
func hide(alert:UIView,overlay:UIView) {
if animated {
UIView.animateWithDuration(0.15, animations: {
overlay.alpha = 0.0
alert.alpha = 0.0
}) {
if $0 {
self.view.sendSubviewToBack(alert)
self.view.sendSubviewToBack(overlay)
self.alertDidDismiss()
}
}
} else {
overlay.alpha = 0.0
alert.alpha = 0.0
view.sendSubviewToBack(alert)
view.sendSubviewToBack(overlay)
alertDidDismiss()
}
}
let overlay = createOverlay()
let alert = createAlert()
hide(alert, overlay: overlay)
}
}
作品:
import UIKit
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
let vc = UIViewController()
let window = UIWindow(frame: UIScreen.mainScreen().bounds)
window.makeKeyAndVisible()
window.rootViewController = vc
vc.view.backgroundColor = UIColor.greenColor()
XCPlaygroundPage.currentPage.liveView = vc.view
let pop = PopUp()
pop.showAlert(animated: true)
alertwilldisease
和alertdidisease
是不需要的,但是它们很好地遵循了标准的UIKit流程,并为您提供了更多的控制
class VC : UIViewController, PopUpAble {
func button1() {
print("button1")
}
func button2() {
print("button2")
}
func button3() {
print("button3")
}
func alertWillDismiss() -> Bool {
return true
}
func alertDidDismiss() {
print("dismissed")
}
func dismissAlert() { // this bridges between objc en swift
self.hideAlert()
}
}
let vc = VC()
vc.view.backgroundColor = UIColor.greenColor()
vc.showAlert(animated: true)
XCPlaygroundPage.currentPage.liveView = vc.view
另一种方法是获取当前可见的viewcontroller并在其上显示警报。它们不是在
UIViewController
子类中定义动作,而是在PopUp
对象中实现。需要时,将从任何位置创建一个弹出窗口
,它将显示在当前VC上
素材:
import UIKit
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
let vc = UIViewController()
let window = UIWindow(frame: UIScreen.mainScreen().bounds)
window.makeKeyAndVisible()
window.rootViewController = vc
vc.view.backgroundColor = UIColor.greenColor()
XCPlaygroundPage.currentPage.liveView = vc.view
let pop = PopUp()
pop.showAlert(animated: true)
当前视图控制器:
import UIKit
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
let vc = UIViewController()
let window = UIWindow(frame: UIScreen.mainScreen().bounds)
window.makeKeyAndVisible()
window.rootViewController = vc
vc.view.backgroundColor = UIColor.greenColor()
XCPlaygroundPage.currentPage.liveView = vc.view
let pop = PopUp()
pop.showAlert(animated: true)
不能把这个代码归功于你,是从某处来的。(如果某人有链接?)
与另一个答案相同:
protocol AlertType : class {}
protocol OverlayType : class {}
class AlertView : UIView, AlertType {}
class OverlayView : UIView, OverlayType {}
弹出对象:
import UIKit
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
let vc = UIViewController()
let window = UIWindow(frame: UIScreen.mainScreen().bounds)
window.makeKeyAndVisible()
window.rootViewController = vc
vc.view.backgroundColor = UIColor.greenColor()
XCPlaygroundPage.currentPage.liveView = vc.view
let pop = PopUp()
pop.showAlert(animated: true)
子类化可用于重写操作
class PopUp : NSObject {
func button1Tapped() {
print("button1")
}
func button2Tapped() {
print("button2")
}
func button3Tapped() {
print("button3")
}
func alertWillDismiss() -> Bool {
return true
}
func alertDidDismiss() {
print("dismissed")
}
这现在在弹出的
中实现
抓取当前VC的视图
,用于显示警报
func createOverlay() -> UIView? {
guard let window = UIApplication.sharedApplication().windows.first, view = window.visibleViewController?.view else {
return nil
}
if let overlay = (view.subviews.filter { $0 is OverlayType }).first {
return overlay
}
let p = CGRectMake(view.frame.origin.x, view.frame.origin.y, view.bounds.size.width, view.bounds.size.height)
let overlayView = OverlayView(frame: p)
overlayView.backgroundColor = UIColor.grayColor()
overlayView.alpha = 0.0
view.insertSubview(overlayView, atIndex: 0)
return overlayView
}
func createAlert() -> UIView? {
guard let window = UIApplication.sharedApplication().windows.first, view = window.visibleViewController?.view else {
return nil
}
if let alert = (view.subviews.filter { $0 is AlertType }).first {
return alert
}
let alertWidth: CGFloat = UIScreen.mainScreen().bounds.width
let alertHeight: CGFloat = UIScreen.mainScreen().bounds.height
let alertViewFrame: CGRect = CGRectMake(0,0, alertWidth, alertHeight)
let alertView = AlertView(frame: alertViewFrame)
alertView.center = view.center
alertView.backgroundColor = UIColor.clearColor()
alertView.alpha = 0.0
let button = UIButton(type: UIButtonType.System)
button.setTitle("Cancel", forState: UIControlState.Normal)
button.setTitleColor(UIColor.redColor(), forState: UIControlState.Normal)
button.backgroundColor = UIColor.clearColor()
button.frame = CGRectMake(0, 0, view.frame.width, view.frame.height)
button.addTarget(self, action: #selector(dismissAlert), forControlEvents: UIControlEvents.TouchUpInside)
button.center.x = alertView.center.x
let button1 = UIButton(type: UIButtonType.RoundedRect)
button1.setTitle("Send", forState: UIControlState.Normal)
button1.backgroundColor = UIColor.greenColor()
button1.frame = CGRectMake(100, 100, 80.0, 80.0)
button1.addTarget(self, action: #selector(button1Tapped), forControlEvents: UIControlEvents.TouchUpInside)
button1.center.x = alertView.center.x
let button2 = UIButton(type: UIButtonType.RoundedRect)
button2.setTitle("Send", forState: UIControlState.Normal)
button2.backgroundColor = UIColor.greenColor()
button2.frame = CGRectMake(100, 200, 80.0, 80.0)
button2.addTarget(self, action: #selector(button2Tapped), forControlEvents: UIControlEvents.TouchUpInside)
button2.center.x = alertView.center.x
let button3 = UIButton(type: UIButtonType.RoundedRect)
button3.setTitle("Send", forState: UIControlState.Normal)
button3.backgroundColor = UIColor.greenColor()
button3.frame = CGRectMake(100, 300, 80.0, 80.0)
button3.addTarget(self, action: #selector(button3Tapped), forControlEvents: UIControlEvents.TouchUpInside)
button3.center.x = alertView.center.x
alertView.addSubview(button)
alertView.addSubview(button1)
alertView.addSubview(button2)
alertView.addSubview(button3)
view.insertSubview(alertView, atIndex: 1)
return alertView
}
func showAlert(animated animated:Bool = true) {
guard let window = UIApplication.sharedApplication().windows.first, view = window.visibleViewController?.view else {
return
}
guard let overlay = createOverlay(), alert = createAlert() else {
return
}
func show(alert:UIView,overlay:UIView) {
if animated {
UIView.animateWithDuration(0.3) {
overlay.alpha = 0.5
alert.alpha = 1.0
}
} else {
overlay.alpha = 0.5
alert.alpha = 1.0
}
}
view.bringSubviewToFront(overlay)
view.bringSubviewToFront(alert)
show(alert, overlay: overlay)
}
func dismissAlert(animated animated:Bool = true) {
guard let window = UIApplication.sharedApplication().windows.first, view = window.visibleViewController?.view else {
return
}
guard let overlay = createOverlay(), alert = createAlert() else {
return
}
func hide(alert:UIView,overlay:UIView) {
if animated {
UIView.animateWithDuration(0.15, animations: {
overlay.alpha = 0.0
alert.alpha = 0.0
}) {
if $0 {
view.sendSubviewToBack(alert)
view.sendSubviewToBack(overlay)
self.alertDidDismiss()
}
}
} else {
overlay.alpha = 0.0
alert.alpha = 0.0
view.sendSubviewToBack(alert)
view.sendSubviewToBack(overlay)
alertDidDismiss()
}
}
hide(alert, overlay: overlay)
}
}
作品:
import UIKit
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
let vc = UIViewController()
let window = UIWindow(frame: UIScreen.mainScreen().bounds)
window.makeKeyAndVisible()
window.rootViewController = vc
vc.view.backgroundColor = UIColor.greenColor()
XCPlaygroundPage.currentPage.liveView = vc.view
let pop = PopUp()
pop.showAlert(animated: true)
注意:
import UIKit
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
let vc = UIViewController()
let window = UIWindow(frame: UIScreen.mainScreen().bounds)
window.makeKeyAndVisible()
window.rootViewController = vc
vc.view.backgroundColor = UIColor.greenColor()
XCPlaygroundPage.currentPage.liveView = vc.view
let pop = PopUp()
pop.showAlert(animated: true)
隐藏后,我将从视图中删除警报和覆盖。没有必要把它们留在身边