我需要执行一个动作(清空一个数组),当UINavigationController的后退按钮被按下,而按钮仍然导致堆栈上的前一个ViewController出现。我如何使用swift来实现这一点?
当前回答
试试这个。
self.navigationItem.leftBarButtonItem?.target = "methodname"
func methodname ( ) {
// enter code here
}
这个也试试。
override func viewWillAppear(animated: Bool) {
//empty your array
}
其他回答
在Swift 5和Xcode 10.2中
请不要添加自定义栏按钮项,使用默认行为。
不需要viewWillDisappear,不需要自定义BarButtonItem等…
最好是检测VC何时从其父对象中移除。
使用这两个函数中的任意一个
override func willMove(toParent parent: UIViewController?) {
super.willMove(toParent: parent)
if parent == nil {
callStatusDelegate?.backButtonClicked()//Here write your code
}
}
override func didMove(toParent parent: UIViewController?) {
super.didMove(toParent: parent)
if parent == nil {
callStatusDelegate?.backButtonClicked()//Here write your code
}
}
如果你想停止返回按钮的默认行为,然后添加自定义BarButtonItem。
我通过调用/重写viewWillDisappear来实现这一点,然后像这样访问navigationController的堆栈:
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
let stack = self.navigationController?.viewControllers.count
if stack >= 2 {
// for whatever reason, the last item on the stack is the TaskBuilderViewController (not self), so we only use -1 to access it
if let lastitem = self.navigationController?.viewControllers[stack! - 1] as? theViewControllerYoureTryingToAccess {
// hand over the data via public property or call a public method of theViewControllerYoureTryingToAccess, like
lastitem.emptyArray()
lastitem.value = 5
}
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if self.isMovingToParent {
//your code backView
}
}
我创建了这个(swift)类来创建一个完全像常规按钮一样的返回按钮,包括返回箭头。它可以创建带有常规文本或图像的按钮。
使用
weak var weakSelf = self
// Assign back button with back arrow and text (exactly like default back button)
navigationItem.leftBarButtonItems = CustomBackButton.createWithText("YourBackButtonTitle", color: UIColor.yourColor(), target: weakSelf, action: #selector(YourViewController.tappedBackButton))
// Assign back button with back arrow and image
navigationItem.leftBarButtonItems = CustomBackButton.createWithImage(UIImage(named: "yourImageName")!, color: UIColor.yourColor(), target: weakSelf, action: #selector(YourViewController.tappedBackButton))
func tappedBackButton() {
// Do your thing
self.navigationController!.popViewControllerAnimated(true)
}
自定义后退按钮类
(使用Sketch & Paintcode插件绘制后退箭头的代码)
class CustomBackButton: NSObject {
class func createWithText(text: String, color: UIColor, target: AnyObject?, action: Selector) -> [UIBarButtonItem] {
let negativeSpacer = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FixedSpace, target: nil, action: nil)
negativeSpacer.width = -8
let backArrowImage = imageOfBackArrow(color: color)
let backArrowButton = UIBarButtonItem(image: backArrowImage, style: UIBarButtonItemStyle.Plain, target: target, action: action)
let backTextButton = UIBarButtonItem(title: text, style: UIBarButtonItemStyle.Plain , target: target, action: action)
backTextButton.setTitlePositionAdjustment(UIOffset(horizontal: -12.0, vertical: 0.0), forBarMetrics: UIBarMetrics.Default)
return [negativeSpacer, backArrowButton, backTextButton]
}
class func createWithImage(image: UIImage, color: UIColor, target: AnyObject?, action: Selector) -> [UIBarButtonItem] {
// recommended maximum image height 22 points (i.e. 22 @1x, 44 @2x, 66 @3x)
let negativeSpacer = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FixedSpace, target: nil, action: nil)
negativeSpacer.width = -8
let backArrowImageView = UIImageView(image: imageOfBackArrow(color: color))
let backImageView = UIImageView(image: image)
let customBarButton = UIButton(frame: CGRectMake(0,0,22 + backImageView.frame.width,22))
backImageView.frame = CGRectMake(22, 0, backImageView.frame.width, backImageView.frame.height)
customBarButton.addSubview(backArrowImageView)
customBarButton.addSubview(backImageView)
customBarButton.addTarget(target, action: action, forControlEvents: .TouchUpInside)
return [negativeSpacer, UIBarButtonItem(customView: customBarButton)]
}
private class func drawBackArrow(frame frame: CGRect = CGRect(x: 0, y: 0, width: 14, height: 22), color: UIColor = UIColor(hue: 0.59, saturation: 0.674, brightness: 0.886, alpha: 1), resizing: ResizingBehavior = .AspectFit) {
/// General Declarations
let context = UIGraphicsGetCurrentContext()!
/// Resize To Frame
CGContextSaveGState(context)
let resizedFrame = resizing.apply(rect: CGRect(x: 0, y: 0, width: 14, height: 22), target: frame)
CGContextTranslateCTM(context, resizedFrame.minX, resizedFrame.minY)
let resizedScale = CGSize(width: resizedFrame.width / 14, height: resizedFrame.height / 22)
CGContextScaleCTM(context, resizedScale.width, resizedScale.height)
/// Line
let line = UIBezierPath()
line.moveToPoint(CGPoint(x: 9, y: 9))
line.addLineToPoint(CGPoint.zero)
CGContextSaveGState(context)
CGContextTranslateCTM(context, 3, 11)
line.lineCapStyle = .Square
line.lineWidth = 3
color.setStroke()
line.stroke()
CGContextRestoreGState(context)
/// Line Copy
let lineCopy = UIBezierPath()
lineCopy.moveToPoint(CGPoint(x: 9, y: 0))
lineCopy.addLineToPoint(CGPoint(x: 0, y: 9))
CGContextSaveGState(context)
CGContextTranslateCTM(context, 3, 2)
lineCopy.lineCapStyle = .Square
lineCopy.lineWidth = 3
color.setStroke()
lineCopy.stroke()
CGContextRestoreGState(context)
CGContextRestoreGState(context)
}
private class func imageOfBackArrow(size size: CGSize = CGSize(width: 14, height: 22), color: UIColor = UIColor(hue: 0.59, saturation: 0.674, brightness: 0.886, alpha: 1), resizing: ResizingBehavior = .AspectFit) -> UIImage {
var image: UIImage
UIGraphicsBeginImageContextWithOptions(size, false, 0)
drawBackArrow(frame: CGRect(origin: CGPoint.zero, size: size), color: color, resizing: resizing)
image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
private enum ResizingBehavior {
case AspectFit /// The content is proportionally resized to fit into the target rectangle.
case AspectFill /// The content is proportionally resized to completely fill the target rectangle.
case Stretch /// The content is stretched to match the entire target rectangle.
case Center /// The content is centered in the target rectangle, but it is NOT resized.
func apply(rect rect: CGRect, target: CGRect) -> CGRect {
if rect == target || target == CGRect.zero {
return rect
}
var scales = CGSize.zero
scales.width = abs(target.width / rect.width)
scales.height = abs(target.height / rect.height)
switch self {
case .AspectFit:
scales.width = min(scales.width, scales.height)
scales.height = scales.width
case .AspectFill:
scales.width = max(scales.width, scales.height)
scales.height = scales.width
case .Stretch:
break
case .Center:
scales.width = 1
scales.height = 1
}
var result = rect.standardized
result.size.width *= scales.width
result.size.height *= scales.height
result.origin.x = target.minX + (target.width - result.width) / 2
result.origin.y = target.minY + (target.height - result.height) / 2
return result
}
}
}
斯威夫特3.0
class CustomBackButton: NSObject {
class func createWithText(text: String, color: UIColor, target: AnyObject?, action: Selector) -> [UIBarButtonItem] {
let negativeSpacer = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.fixedSpace, target: nil, action: nil)
negativeSpacer.width = -8
let backArrowImage = imageOfBackArrow(color: color)
let backArrowButton = UIBarButtonItem(image: backArrowImage, style: UIBarButtonItemStyle.plain, target: target, action: action)
let backTextButton = UIBarButtonItem(title: text, style: UIBarButtonItemStyle.plain , target: target, action: action)
backTextButton.setTitlePositionAdjustment(UIOffset(horizontal: -12.0, vertical: 0.0), for: UIBarMetrics.default)
return [negativeSpacer, backArrowButton, backTextButton]
}
class func createWithImage(image: UIImage, color: UIColor, target: AnyObject?, action: Selector) -> [UIBarButtonItem] {
// recommended maximum image height 22 points (i.e. 22 @1x, 44 @2x, 66 @3x)
let negativeSpacer = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.fixedSpace, target: nil, action: nil)
negativeSpacer.width = -8
let backArrowImageView = UIImageView(image: imageOfBackArrow(color: color))
let backImageView = UIImageView(image: image)
let customBarButton = UIButton(frame: CGRect(x: 0, y: 0, width: 22 + backImageView.frame.width, height: 22))
backImageView.frame = CGRect(x: 22, y: 0, width: backImageView.frame.width, height: backImageView.frame.height)
customBarButton.addSubview(backArrowImageView)
customBarButton.addSubview(backImageView)
customBarButton.addTarget(target, action: action, for: .touchUpInside)
return [negativeSpacer, UIBarButtonItem(customView: customBarButton)]
}
private class func drawBackArrow(_ frame: CGRect = CGRect(x: 0, y: 0, width: 14, height: 22), color: UIColor = UIColor(hue: 0.59, saturation: 0.674, brightness: 0.886, alpha: 1), resizing: ResizingBehavior = .AspectFit) {
/// General Declarations
let context = UIGraphicsGetCurrentContext()!
/// Resize To Frame
context.saveGState()
let resizedFrame = resizing.apply(CGRect(x: 0, y: 0, width: 14, height: 22), target: frame)
context.translateBy(x: resizedFrame.minX, y: resizedFrame.minY)
let resizedScale = CGSize(width: resizedFrame.width / 14, height: resizedFrame.height / 22)
context.scaleBy(x: resizedScale.width, y: resizedScale.height)
/// Line
let line = UIBezierPath()
line.move(to: CGPoint(x: 9, y: 9))
line.addLine(to: CGPoint.zero)
context.saveGState()
context.translateBy(x: 3, y: 11)
line.lineCapStyle = .square
line.lineWidth = 3
color.setStroke()
line.stroke()
context.restoreGState()
/// Line Copy
let lineCopy = UIBezierPath()
lineCopy.move(to: CGPoint(x: 9, y: 0))
lineCopy.addLine(to: CGPoint(x: 0, y: 9))
context.saveGState()
context.translateBy(x: 3, y: 2)
lineCopy.lineCapStyle = .square
lineCopy.lineWidth = 3
color.setStroke()
lineCopy.stroke()
context.restoreGState()
context.restoreGState()
}
private class func imageOfBackArrow(_ size: CGSize = CGSize(width: 14, height: 22), color: UIColor = UIColor(hue: 0.59, saturation: 0.674, brightness: 0.886, alpha: 1), resizing: ResizingBehavior = .AspectFit) -> UIImage {
var image: UIImage
UIGraphicsBeginImageContextWithOptions(size, false, 0)
drawBackArrow(CGRect(origin: CGPoint.zero, size: size), color: color, resizing: resizing)
image = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
}
private enum ResizingBehavior {
case AspectFit /// The content is proportionally resized to fit into the target rectangle.
case AspectFill /// The content is proportionally resized to completely fill the target rectangle.
case Stretch /// The content is stretched to match the entire target rectangle.
case Center /// The content is centered in the target rectangle, but it is NOT resized.
func apply(_ rect: CGRect, target: CGRect) -> CGRect {
if rect == target || target == CGRect.zero {
return rect
}
var scales = CGSize.zero
scales.width = abs(target.width / rect.width)
scales.height = abs(target.height / rect.height)
switch self {
case .AspectFit:
scales.width = min(scales.width, scales.height)
scales.height = scales.width
case .AspectFill:
scales.width = max(scales.width, scales.height)
scales.height = scales.width
case .Stretch:
break
case .Center:
scales.width = 1
scales.height = 1
}
var result = rect.standardized
result.size.width *= scales.width
result.size.height *= scales.height
result.origin.x = target.minX + (target.width - result.width) / 2
result.origin.y = target.minY + (target.height - result.height) / 2
return result
}
}
}
Swift 5+(带警报控制的后退按钮)
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.hidesBackButton = true
let newBackButton = UIBarButtonItem(title: "<Back", style: UIBarButtonItem.Style.plain, target: self, action: #selector(PGWebViewController.back(sender:)))
self.navigationItem.leftBarButtonItem = newBackButton
}
@objc func back(sender: UIBarButtonItem) {
let alert = UIAlertController(title: "Warning!", message: "Your payment process is not completed yet. Do you want to go back?", preferredStyle: .alert)
let ok = UIAlertAction(title: "OK", style: .default, handler: { action in
_ = self.navigationController?.popViewController(animated: true)
})
alert.addAction(ok)
let cancel = UIAlertAction(title: "Cancel", style: .default, handler: { action in
})
alert.addAction(cancel)
DispatchQueue.main.async(execute: {
self.present(alert, animated: true)
})}
推荐文章
- swift语言中的结构与类
- 我如何在Swift连接字符串?
- 请求失败:不可接受的内容类型:文本/html使用AFNetworking 2.0
- 缺少推荐的图标文件-该包不包含iPhone / iPod Touch的应用程序图标,像素为“120x120”,png格式
- 以编程方式创建segue
- Xcode 10的对象库去哪了?
- Xcode 10的UI元素在哪里?
- 我应该如何从字符串中删除所有的前导空格?- - - - - -斯威夫特
- Xcode构建失败“架构x86_64未定义的符号”
- 如何使用Xcode创建。ipa文件?
- 我可以在没有“构建和运行”的情况下启动iPhone模拟器吗?
- 动态改变UILabel的字体大小
- Xcode 4 -在新的Macintosh安装上的配置文件上“没有找到有效的签名标识”错误
- Xcode +删除所有断点
- 在iPhone上确定用户是否启用了推送通知