Swift / UIView带有TableView和手势识别器问题

时间:2016-07-26 20:52:11

标签: ios swift tableview

我有一个带有TableView和2(tap)手势识别器的UIViewController。 第一个识别器让键盘消失。第二个菜单。

    let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(HomeVC.dismissKeyboard))
    view.addGestureRecognizer(tap)

-

    @IBAction func menuBtn(sender: AnyObject) {

    let menuView = (NSBundle.mainBundle().loadNibNamed("Menu", owner: self, options: nil).last) as! Menu
    menuView.frame = CGRectMake(0, self.view.bounds.size.height, self.view.bounds.size.width, 100)

    self.view.addSubview(menuView)

    UIView.animateWithDuration(0.6, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.8, options: .CurveEaseInOut, animations: { () -> Void in
        var newMenuFrame = menuView.frame
        newMenuFrame.origin.y = self.view.bounds.size.height - 63
        menuView.frame = newMenuFrame
        self.view.layoutIfNeeded()



    }) { (success) -> Void in

        let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(HomeVC.hideOnTap(_:)))
        gestureRecognizer.numberOfTapsRequired = 1
        self.view.addGestureRecognizer(gestureRecognizer)
    }

}

使用手势regonizers,didSelectRowAtIndexPath将不会被调用。我该怎么做才能保持手势识别器和我的tableView。要么。如何仅为tableView停用手势识别器?非常感谢帮助。

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    print("You selected cell #\(indexPath.row)!")
    // this is only working if both gesture recognizers are gone.

}

/////完整代码

//
//  HomeVC.swift
//  cya
//
//  Created by David Seek on 25.07.16.
//  Copyright © 2016 David Seek. All rights reserved.
//

import UIKit
import FBSDKCoreKit
import FBSDKLoginKit
import GoogleMobileAds
import SDWebImage

protocol ChooseUserDelegade {
    func createChatroom(withUser: BackendlessUser)
}

class HomeVC: UIViewController, UITextFieldDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UITableViewDelegate, UITableViewDataSource {

    var deejays: [BackendlessUser] = []
    var delegade: ChooseUserDelegade!

    @IBOutlet weak var avatarImageView: UIImageView!
    @IBOutlet weak var coverImageView: UIImageView!

    @IBOutlet weak var statusTextField: UITextField!
    @IBOutlet weak var googleAdBannerView: GADBannerView!

    @IBOutlet weak var tableView: UITableView!
    var menu: Menu!

    override func viewDidLoad() {
        super.viewDidLoad()

        print("Google Mobile Ads SDK version: \(GADRequest.sdkVersion())")
        //googleAdBannerView.adUnitID = "//" //live ad
        googleAdBannerView.adUnitID = "//" //test ad
        googleAdBannerView.rootViewController = self
        googleAdBannerView.loadRequest(GADRequest())

        avatarImageView.layer.cornerRadius = avatarImageView.frame.size.width / 2
        avatarImageView.layer.masksToBounds = true
        avatarImageView.layer.borderWidth = 1
        avatarImageView.layer.borderColor = UIColor.whiteColor().CGColor

        updateUI()

        let tapGestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(HomeVC.dismissKeyboard))
        tapGestureRecognizer.delegate = self
        view.addGestureRecognizer(tapGestureRecognizer)


        self.statusTextField.delegate = self

        self.tableView.rowHeight = 80
        loadDeejays()


    }

    @IBAction func menuBtn(sender: AnyObject) {

        let menuView = (NSBundle.mainBundle().loadNibNamed("Menu", owner: self, options: nil).last) as! Menu
        menuView.frame = CGRectMake(0, self.view.bounds.size.height, self.view.bounds.size.width, 100)

        self.view.addSubview(menuView)

        UIView.animateWithDuration(0.6, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.8, options: .CurveEaseInOut, animations: { () -> Void in
            var newMenuFrame = menuView.frame
            newMenuFrame.origin.y = self.view.bounds.size.height - 63
            menuView.frame = newMenuFrame
            self.view.layoutIfNeeded()

        }) { (success) -> Void in

            let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(HomeVC.hideOnTap(_:)))
            gestureRecognizer.numberOfTapsRequired = 1
            gestureRecognizer.delegate = self
            self.view.addGestureRecognizer(gestureRecognizer)
        }

    }

    func hideOnTap(recognizer: UITapGestureRecognizer) {
        self.view.viewWithTag(5)?.removeFromSuperview()
    }

    @IBAction func changeAvatarBtn(sender: AnyObject) {

        changePhoto()        
    }

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

    func updateUI() {

        if let imageLink = backendless.userService.currentUser.getProperty("Avatar") as? String {

            getImageFromURL(imageLink, result: { (image) in
                self.avatarImageView.image = image
            })
        }
    }

    @IBAction func testLogout(sender: AnyObject) {
        showLogoutView()
    }

    func showLogoutView() {

        let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)
        let logout = UIAlertAction(title: "Logout", style: .Destructive) { (alert : UIAlertAction!) in
            self.logoutFunc()
        }

        let cancel = UIAlertAction(title: "Cancel", style: .Cancel) { (alert : UIAlertAction) in
            //
        }

        optionMenu.addAction(logout)
        optionMenu.addAction(cancel)

        self.presentViewController(optionMenu, animated: true, completion: nil)
    }

    func logoutFunc() {

        if FBSDKAccessToken.currentAccessToken() != nil {
            let loginManager = FBSDKLoginManager()
            loginManager.logOut()
        }

        backendless.userService.logout()
        let registerVC = storyboard?.instantiateViewControllerWithIdentifier("RegisterVC")
        self.presentViewController(registerVC!, animated: true, completion: nil)
    }

    func changePhoto() {

        let camera = Camera(delegate_: self)

        let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)
        let takePhoto = UIAlertAction(title: "Camera", style: .Default) { (alert : UIAlertAction!) in
            camera.presentPhotoCamera(self, canEdit: true)
        }
        let sharePhoto = UIAlertAction(title: "Library", style: .Default) { (alert : UIAlertAction) in
            camera.presentPhotoLibrary(self, canEdit: true)
        }
        //MARK: TODO
        /*let showPicture = UIAlertAction(title: "Show Picture", style: .Default) { (alert : UIAlertAction) in
            //
        }
        let loadPicFromFacebook = UIAlertAction(title: "Load from Facebook", style: .Default) { (alert : UIAlertAction) in
            //
        }*/
        let cancel = UIAlertAction(title: "Cancel", style: .Cancel) { (alert : UIAlertAction) in
            //
        }

        optionMenu.addAction(takePhoto)
        optionMenu.addAction(sharePhoto)
        //optionMenu.addAction(showPicture)
        //optionMenu.addAction(loadPicFromFacebook)
        optionMenu.addAction(cancel)

        self.presentViewController(optionMenu, animated: true, completion: nil)
    }

    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {

        let image = info[UIImagePickerControllerEditedImage] as! UIImage
        uploadAvatar(image) { (imageLink) in
            let properties = ["Avatar" : imageLink!]
            backendless.userService.currentUser.updateProperties(properties)
            backendless.userService.update(backendless.userService.currentUser, response: { (updatedUser : BackendlessUser!) in

                print("User: \(updatedUser.name) successfully updated")
                self.updateUI()
                }, error: { (fault : Fault!) in


  print(fault)
        })
    }

    picker.dismissViewControllerAnimated(true, completion: nil)
}

func dismissKeyboard() {
    view.endEditing(true)
}

func textFieldShouldReturn(textField: UITextField) -> Bool {
    self.view.endEditing(true)
    return false
}

override func preferredStatusBarStyle() -> UIStatusBarStyle {
    return UIStatusBarStyle.LightContent;
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("djListCell", forIndexPath: indexPath) as! DJListCell
    let user = deejays[indexPath.row]
    //cell.textLabel?.text = user.name

    cell.djNameLabel.text = user.getProperty("deejayName") as? String
    cell.djGenreLabel.text = user.getProperty("genre") as? String

    let imgURL = NSURL(string: user.getProperty("Avatar") as! String)
    cell.djAvatarImageView.sd_setImageWithURL(imgURL)

    let residentAt = user.getProperty("residentAt") as? String
    cell.djResidentAtLabel.text = residentAt

    /*
    if let imageLink = user.getProperty("Avatar") as? String {

        getImageFromURL(imageLink, result: { (image) in
            cell.djAvatarImageView.image = image
        })
    }*/

    let date = dateFormatter().dateFromString(user.getProperty("lastOnlineString") as! String)
    let seconds = NSDate().timeIntervalSinceDate(date!)

    if timeElapsed(seconds) != "Just now" {
        cell.djLastOnlineLabel.text = "last online: \(timeElapsed(seconds)) ago"
    } else {
        cell.djLastOnlineLabel.text = timeElapsed(seconds)
    }
    return cell
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return deejays.count
}

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    print("You selected cell #\(indexPath.row)!")
    //let user = deejays[indexPath.row]
    //delegade.createChatroom(user)

    //self.tableView.deselectRowAtIndexPath(indexPath, animated: true)
    //self.dismissViewControllerAnimated(true, completion: nil)

    //let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("DJProfileAsUserVC")


    //dispatch_async(dispatch_get_main_queue()) {
    //    self.presentViewController(vc, animated: true, completion: nil)
    //}



}

func loadDeejays() {

    //let whereClause = "objectId != '\(backendless.userService.currentUser.objectId)'"
    let whereClause = "isDJ = True"
    let dataQuery = BackendlessDataQuery()
    dataQuery.whereClause = whereClause

    let dataStore = backendless.persistenceService.of(BackendlessUser.ofClass())
    dataStore.find(dataQuery, response: { (users : BackendlessCollection!) in

        self.deejays = users.data as! [BackendlessUser]
        self.tableView.reloadData()

    }) { (fault : Fault!) in
        print("error: \(fault)")
    }
}

func timeElapsed(seconds: NSTimeInterval) -> String {
    let elapsed: String?
    if seconds < 60 {
        elapsed = "Just now"
    } else if (seconds < 60 * 60) {
        let minutes = Int(seconds / 60)

        var minText = "min"
        if minutes > 1 {
            minText = "mins"
        }
        elapsed = "\(minutes) \(minText)"
    } else if (seconds < 24 * 60 * 60) {
        let hours = Int(seconds / (60 * 60))
        var hourText = "hour"
        if hours > 1 {
            hourText = "hours"
        }
        elapsed = "\(hours) \(hourText)"
    } else {
        let days = Int(seconds / (24 * 60 * 60))
        var dayText = "day"
        if days > 1 {
            dayText = "days"
        }
        elapsed = "\(days) \(dayText)"
    }
    return elapsed!
}

}

extension HomeVC: UIGestureRecognizerDelegate {
    func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
}

2 个答案:

答案 0 :(得分:1)

设置cancelsTouchesInView可能有所帮助:

tap.cancelsTouchesInView = false
longtap.cancelsTouchesInView = false

通常,您可以让方法shouldRecognizeSimultaneouslyWithGestureRecognizer返回true并添加相应的委托来让识别器与其他识别器一起使用。

答案 1 :(得分:1)

你应该覆盖

optional func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool
来自UIGestureRecognizerDelegate的

识别同时手势。更多https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIGestureRecognizerDelegate_Protocol/#//apple_ref/occ/intfm/UIGestureRecognizerDelegate/gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: