Я думаю, что волшебство, которое вы ищете, это
func getTopViewController(_ viewController: UIViewController? = UIApplication.shared.delegate?.window??.rootViewController) -> UIViewController? {
if let tabBarViewController = viewController as? UITabBarController {
return getTopViewController(tabBarViewController.selectedViewController)
} else if let navigationController = viewController as? UINavigationController {
return getTopViewController(navigationController.visibleViewController)
} else if let presentedViewController = viewController?.presentedViewController {
return getTopViewController(presentedViewController)
} else {
return viewController
}
}
Я ненавижу использовать его, потому что он не придерживается лучших практик Apple, но в крайнем случае он подойдет для более простых раскадровок. Вы можете использовать это представление контроллеров представления, чтобы добавить сообщение к
if let viewController = getTopViewController() {
let toastLabel = UILabel(frame: frame)
// set up labels background color and other properties...
toastLabel.text = "your message"
// add the subview to the rootViewController
viewController.view.addSubview(toastLabel)
// easy animation
UIView.animate(withDuration: 0.4, delay: duration, options: .curveEaseOut, animations: {
toastLabel.alpha = 0.0
}, completion: {(isCompleted) in
toastLabel.removeFromSuperview()
})
} else {
print("Unable to get top view controller.")
}
Убедитесь, что используете это только в основной очереди отправки
DispatchQueue.main.async {
// ...
}
Ниже приведено несколько приемов, позволяющих сделать этот модуль более ориентированным на модуль и объект.
Один из приемов - использовать статический класс тостов .
import UIKit
public class Toast {
private init() { }
public static var frame = CGRect(
x: UIScreen.main.bounds.size.width/2 - (UIScreen.main.bounds.size.width/2 - 16),
y: UIScreen.main.bounds.size.height - 100,
width: UIScreen.main.bounds.size.width - 32,
height: 35
)
public static var backgroundColor = UIColor.black.withAlphaComponent(0.6)
public static var textColor = UIColor.white
public static var textAlignment = NSTextAlignment.center
public static var font = UIFont.systemFont(ofSize: 12.0)
public static var alpha:CGFloat = 1.0
public static var cornerRadius:CGFloat = 10.0;
public static func makeToast(
message: String,
duration: TimeInterval = 4.0,
completion: ((_ complete:Bool)->Void)? = nil
) {
if let viewController = getTopViewController() {
let toastLabel = UILabel(frame: Toast.frame)
toastLabel.backgroundColor = Toast.backgroundColor
toastLabel.textColor = Toast.textColor
toastLabel.textAlignment = Toast.textAlignment;
toastLabel.font = Toast.font
toastLabel.alpha = Toast.alpha
toastLabel.layer.cornerRadius = Toast.cornerRadius
toastLabel.clipsToBounds = true
toastLabel.text = message
viewController.view.addSubview(toastLabel)
UIView.animate(withDuration: 0.4, delay: duration, options: .curveEaseOut, animations: {
toastLabel.alpha = 0.0
}, completion: {(isCompleted) in
toastLabel.removeFromSuperview()
completion?(isCompleted)
})
} else {
print("Unable to get top view controller.")
}
}
private static func getTopViewController(_ viewController: UIViewController? = UIApplication.shared.delegate?.window??.rootViewController) -> UIViewController? {
if let tabBarViewController = viewController as? UITabBarController {
return getTopViewController(tabBarViewController.selectedViewController)
} else if let navigationController = viewController as? UINavigationController {
return getTopViewController(navigationController.visibleViewController)
} else if let presentedViewController = viewController?.presentedViewController {
return getTopViewController(presentedViewController)
} else {
return viewController
}
}
}
Использование:
Toast.makeToast(message: "This is a test", duration: 4.0) { (isCompleted) in
print("completed: \(isCompleted)")
}
// or
Toast.makeToast(message: "This is a test", duration: 4.0)
// or just
Toast.makeToast(message: "This is a test")
Вы можете установить frame, backgroundColor, textColor, textAlignment, font, alpha и cornerRadius, используя статические переменные следующим образом:
Toast.frame = CGRect(
x: UIScreen.main.bounds.size.width/2 - (UIScreen.main.bounds.size.width/2 - 16),
y: UIScreen.main.bounds.size.height - 100,
width: UIScreen.main.bounds.size.width - 32,
height: 35
)
Toast.backgroundColor = UIColor.blue
Toast.textColor = UIColor.green
Toast.textAlignment = .left
Toast.font = UIFont.systemFont(ofSize: 14.0)
Toast.alpha = 0.8
Toast.cornerRadius = 8.0
Другой метод заключается в расширении UIApplication .
import UIKit
extension UIApplication {
public func makeToast(
message: String,
duration: TimeInterval = 4.0,
frame:CGRect = CGRect(
x: UIScreen.main.bounds.size.width/2 - (UIScreen.main.bounds.size.width/2 - 16),
y: UIScreen.main.bounds.size.height - 100,
width: UIScreen.main.bounds.size.width - 32,
height: 35
),
backgroundColor:UIColor = UIColor.black.withAlphaComponent(0.6),
textColor:UIColor = UIColor.white,
textAlignment:NSTextAlignment = .center,
font:UIFont = UIFont.systemFont(ofSize: 12.0),
alpha:CGFloat = 1.0,
cornerRadius:CGFloat = 10,
completion: ((_ complete:Bool)->Void)? = nil
) {
if let viewController = self.getTopViewController(self.delegate?.window??.rootViewController) {
let toastLabel = UILabel(frame: frame)
toastLabel.backgroundColor = backgroundColor
toastLabel.textColor = textColor
toastLabel.textAlignment = textAlignment;
toastLabel.font = font
toastLabel.alpha = alpha
toastLabel.layer.cornerRadius = cornerRadius
toastLabel.clipsToBounds = true
toastLabel.text = message
viewController.view.addSubview(toastLabel)
UIView.animate(withDuration: 0.4, delay: duration, options: .curveEaseOut, animations: {
toastLabel.alpha = 0.0
}, completion: {(isCompleted) in
toastLabel.removeFromSuperview()
completion?(isCompleted)
})
} else {
print("Unable to get top view controller.")
}
}
private func getTopViewController(_ viewController: UIViewController?) -> UIViewController? {
if let tabBarViewController = viewController as? UITabBarController {
return getTopViewController(tabBarViewController.selectedViewController)
} else if let navigationController = viewController as? UINavigationController {
return getTopViewController(navigationController.visibleViewController)
} else if let presentedViewController = viewController?.presentedViewController {
return getTopViewController(presentedViewController)
} else {
return viewController
}
}
}
Использование:
UIApplication.shared.makeToast(message: "This is another test", duration: 4.0) { (isCompleted) in
print("completed: \(isCompleted)")
}
Вы можете установить frame, backgroundColor, textColor, textAlignment, font, alpha и cornerRadius, передав их в функцию с их тегами:
UIApplication.shared.makeToast(
message: "This is another test",
duration: 4.0,
frame: CGRect(
x: UIScreen.main.bounds.size.width/2 - (UIScreen.main.bounds.size.width/2 - 16),
y: UIScreen.main.bounds.size.height - 100,
width: UIScreen.main.bounds.size.width - 32,
height: 35
),
backgroundColor: UIColor.blue.withAlphaComponent(0.6),
textColor: UIColor.red,
textAlignment: NSTextAlignment.left,
font: UIFont.systemFont(ofSize: 16.0),
alpha: 1.0,
cornerRadius: 10
) { (isCompleted) in
print("completed: \(isCompleted)")
}
Скачать пример
Быстрый гист