#selector函数意外调用

时间:2018-09-25 13:23:17

标签: ios swift uitoolbar

我正在实现UIToolBar,它具有两个按钮:“新建目录”和“编辑(或完成)”。 我编写了以下代码,但是,当我按下“完成按钮”时,将同时调用switchMode函数和createNewDirectory函数(后者仅应从“新建目录”按钮调用)

请给我任何建议。

- 附加评论

我不使用故事板作为工具栏和两个按钮。由于多种原因,我不能采用故事板。

class DetailViewController: UIViewController {
@IBAction func goBack(_ sender: UIButton) {
    self.dismiss(animated: true, completion: nil)
}

var newDirectory: UIBarButtonItem!
var editDirectory: UIBarButtonItem!
var toolbar: UIToolbar!
let flexibleItem = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
var isEditMode: Bool!

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
    toolbar = UIToolbar(frame: CGRect(x: 0, y: self.view.bounds.height - 44, width: self.view.bounds.width, height: 44))
    newDirectory = UIBarButtonItem(title: "New D", style: .plain, target: self, action: #selector(createNewDirectory(_:)))
    newDirectory.isEnabled = false
    newDirectory.tintColor = UIColor.init(white: CGFloat(bitPattern: 0), alpha: CGFloat(bitPattern: 0))

    editDirectory = UIBarButtonItem(title: "Edit", style: .plain, target: self, action: #selector(switchMode(_:)))
    editDirectory.tintColor = self.view.tintColor

    isEditMode = false

    toolbar.items = [newDirectory, flexibleItem, editDirectory]
    self.view.addSubview(toolbar)
}

func createNewDirectory(_ sender: UIBarButtonItem) {
    print("createNewDirectory was called", sender.title!)
}

func switchMode(_ sender: UIBarButtonItem) {
    print("switchMode was called", sender.title!, isEditMode)
    if isEditMode == false {
        isEditMode = true
        newDirectory.isEnabled = true
        newDirectory.tintColor = self.view.tintColor
        sender.title = "Done"

    } else {
        isEditMode = false
        newDirectory.isEnabled = false
        newDirectory.tintColor = UIColor.init(white: CGFloat(bitPattern: 0), alpha: CGFloat(bitPattern: 0))
        sender.title = "Edit"
    }
}
// some other function not related to this post

-

感谢许多有用的评论! 为简化起见,我重新创建了一个示例项目并重现了该问题。

  • 删除了主故事板和相关设置
  • 使用Swift 3.3
  • swift类仅是AppDelegate.swift和ViewController.Swift。 (代码在下面)

AppDelegate.swift

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        self.window = UIWindow(frame: UIScreen.main.bounds)
        let viewController = ViewController()
        self.window?.rootViewController = viewController
        self.window?.makeKeyAndVisible()

        return true
    }

    func applicationWillResignActive(_ application: UIApplication) {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }

    func applicationWillTerminate(_ application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }


}

ViewController.swift

import UIKit

class ViewController: UIViewController {
    var newDirectory: UIBarButtonItem!
    var editDirectory: UIBarButtonItem!
    var toolbar: UIToolbar!
    let flexibleItem = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
    var isEditMode: Bool!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.view.backgroundColor = UIColor.white
        toolbar = UIToolbar(frame: CGRect(x: 0, y: self.view.bounds.height - 44, width: self.view.bounds.width, height: 44))
        newDirectory = UIBarButtonItem(title: "New D", style: .plain, target: self, action: #selector(createNewDirectory(_:)))
        newDirectory.isEnabled = false
        newDirectory.tintColor = UIColor.init(white: CGFloat(bitPattern: 0), alpha: CGFloat(bitPattern: 0))

        editDirectory = UIBarButtonItem(title: "Edit", style: .plain, target: self, action: #selector(switchMode(_:)))
        editDirectory.tintColor = self.view.tintColor

        isEditMode = false

        toolbar.items = [newDirectory, flexibleItem, editDirectory]
        self.view.addSubview(toolbar)
    }

    @objc func createNewDirectory(_ sender: UIBarButtonItem) {
        print("createNewDirectory was called", sender.title!)
    }

    @objc func switchMode(_ sender: UIBarButtonItem) {
        print("switchMode was called", sender.title!, isEditMode)
        if isEditMode == false {
            isEditMode = true
            newDirectory.isEnabled = true
            newDirectory.tintColor = self.view.tintColor
            sender.title = "Done"

        } else {
            isEditMode = false
            newDirectory.isEnabled = false
            newDirectory.tintColor = UIColor.init(white: CGFloat(bitPattern: 0), alpha: CGFloat(bitPattern: 0))
            sender.title = "Edit"
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

1 个答案:

答案 0 :(得分:0)

我重新启动了iOS模拟器,现在可以正常工作了。 不太清楚其之前无法正常运行的确切原因。 但是无论如何,我都会关闭。谢谢大家。

-

对于这个问题,我总共创建了三个项目。 它们全部具有相同的逻辑,并且以相同的方式失败。 重新启动模拟器后,它们全部工作正常。 因此,这似乎是由于模拟器内部问题或其他原因引起的。