我问这个问题是因为我在这个问题中收到了答案:How Do I Initialize Two Instances of NSObject in the same ViewController - Swift
带我走向这个方向。无论我是NASSbject还是UIViewController的子类,当我将代码更改为以下内容时,仍然会收到无法识别的选择器。
我仍然试图创建一个左右SideBar。但是,我现在甚至无法加载一个SideBar。我收到错误[UIViewController Center]:发送到实例xxxxx的无法识别的选择器。
这个问题与我见过的其他无法识别的选择器实例问题有所不同,因为我没有处理按钮而没有出口,因为一切都是以编程方式完成的。因此,我无法指定链接到故事板中UIViewController
的子类。
我觉得一旦我解决了选择器问题,代码就会起作用。由于代码现在,应用程序编译正常。问题是我收到的运行时错误。如果有必要,我可以从调试器提供信息。
Fwiw,似乎运行时正在认识到我从错误消息中有一个中心,左侧和右侧的视图控制器。
我还没有包含RightSideBar代码,因为我认为如果左侧SideBar运行RightSideBar将在我添加解决方案时运行。我希望尽可能简短地阅读您必须阅读的代码。
最后要注意的是,我已经完成了所有的印刷声明。我实际上是打印到它说'#34;我应该显示sideBar"。
以下是SideBar的代码:
//optional delegate methods that select when the sidebar opens and closes.
@objc protocol SideBarDelegate : class {
func sideBarDidSelectButtonAtIndex (itemIndex: Int)
optional func sideBarWillClose()
optional func sideBarWillOpen()
}
//this class sets up the actual sidebar.
class SideBar: UIViewController, SidebarTableViewControllerDelegate {
//width of the bar, tableview setup, and views for the sidebar
let barWidth:CGFloat = 175.0
let sideBarTableViewTopInset:CGFloat = 25.0
let sideBarContainerView:UIViewController = UIViewController()
let sideBarTableViewController:SidebarTableViewController = SidebarTableViewController()
var originView:UIViewController?
//var for dynamic effect and controlling the sidebar
var animator:UIDynamicAnimator!
weak var delegate:SideBarDelegate?
var isSideBarOpen:Bool = false
//initializer for the "SideBar" class.
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(nibName NibNameOrNil:String!, bundle nibBundleOrNil:NSBundle!) {
super.init(nibName: nil, bundle: nil)
}
convenience init(){
self.init(nibName: nil, bundle: nil)
}
//initializer for the tableView of menu items.
init(sourceView: UIViewController, menuItems: Array<String>, menuImages: [UIImage]){
self.originView = sourceView
self.sideBarTableViewController.tableData = menuItems
self.sideBarTableViewController.imageData = menuImages
println("set initialization values")
super.init(nibName: nil, bundle: nil)
//initializing the views and animation for the menu.
setupSideBar()
animator = UIDynamicAnimator(referenceView: originView!.view)
println("finished initialization")
//swipe gesture recognition for opening the menu.
let showGestureRecognizer:UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: "handleSwipe:")
showGestureRecognizer.direction = UISwipeGestureRecognizerDirection.Right
originView!.view.addGestureRecognizer(showGestureRecognizer)
let hideGestureRecognizer:UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: "handleSwipe:")
hideGestureRecognizer.direction = UISwipeGestureRecognizerDirection.Left
originView!.view.addGestureRecognizer(hideGestureRecognizer)
}
override func viewDidLoad() {
println("view loaded")
}
//this function handles the direction of swipes
func handleSwipe(recognizer: UISwipeGestureRecognizer){
if recognizer.direction == UISwipeGestureRecognizerDirection.Left {
showSideBar(false)
delegate?.sideBarWillClose?()
println("closed the sideBar")
} else {
println("opened the sideBar")
showSideBar(true)
delegate?.sideBarWillOpen?()
}
}
//function for setting up the sidebar.
func setupSideBar () {
println("setup sideBar")
//setting up the frame/outline of the side bar.
sideBarContainerView.view.frame = CGRectMake(-barWidth - 1, originView!.view.frame.origin.y, barWidth, originView!.view.frame.size.height)
//setting up the color of the sidebar.
sideBarContainerView.view.backgroundColor = UIColor.clearColor()
//disables subviews from being confined to the sidebar.
sideBarContainerView.view.clipsToBounds = false
//placing the sidebar in the UIView
originView!.view.addSubview(sideBarContainerView.view)
//adding blur to the menu.
let blurView:UIVisualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: UIBlurEffectStyle.Light))
blurView.frame = sideBarContainerView.view.bounds
sideBarContainerView.view.addSubview(blurView)
//setting up controls for the sidebar
sideBarTableViewController.delegate = self
sideBarTableViewController.tableView.frame = sideBarContainerView.view.bounds
sideBarTableViewController.tableView.clipsToBounds = false
//disabling the scroll feature. Delete to keep the scroll feature.
sideBarTableViewController.tableView.scrollsToTop = false
//This will remove separators in the UITableCell. Delete to keep separators.
sideBarTableViewController.tableView.separatorStyle = UITableViewCellSeparatorStyle.None
//This sets the background color of the sidebar and creates the inset.
sideBarTableViewController.tableView.backgroundColor = UIColor.clearColor()
sideBarTableViewController.tableView.contentInset = UIEdgeInsets(top: sideBarTableViewTopInset, left: 0, bottom: 0, right: 0)
//reloads the sidebar and adds the container view to the sideBarTableViewController.
sideBarTableViewController.tableView.reloadData()
sideBarContainerView.view.addSubview(sideBarTableViewController.tableView)
originView?.addChildViewController(sideBarContainerView)
sideBarContainerView.didMoveToParentViewController(originView)
}
func showSideBar(shouldOpen: Bool){
animator.removeAllBehaviors()
isSideBarOpen = shouldOpen
println("I should be showing the sideBar")
//simple if and else statements to define the direction of animation and intensity of animation
let gravityX:CGFloat = (shouldOpen) ? 0.5 : -0.5
let magnitude:CGFloat = (shouldOpen) ? 20 : -20
let boundaryX:CGFloat = (shouldOpen) ? barWidth : -barWidth - 1
//controls the behavior of the animation.
let gravityBehavior: UIGravityBehavior = UIGravityBehavior(items: [sideBarContainerView])
gravityBehavior.gravityDirection = CGVectorMake(gravityX, 0)
animator.addBehavior(gravityBehavior)
let collisionBehavior: UICollisionBehavior = UICollisionBehavior(items: [sideBarContainerView])
collisionBehavior.addBoundaryWithIdentifier("sideBarBoundary", fromPoint: CGPointMake(boundaryX, 20), toPoint: CGPointMake(boundaryX, originView!.view.frame.size.height))
animator.addBehavior(collisionBehavior)
let pushBehavior:UIPushBehavior = UIPushBehavior(items: [sideBarContainerView], mode: UIPushBehaviorMode.Instantaneous)
pushBehavior.magnitude = magnitude
animator.addBehavior(pushBehavior)
let sideBarBehavior:UIDynamicItemBehavior = UIDynamicItemBehavior(items: [sideBarContainerView])
sideBarBehavior.elasticity = 0.3
animator.addBehavior(sideBarBehavior)
}
func sidebarControlDidSelectRow(indexPath: NSIndexPath) {
delegate?.sideBarDidSelectButtonAtIndex(indexPath.row)
}
}
这是Home ViewController:
class Home: UIViewController, SideBarDelegate {
//*** Must put logout code into the logout button it should log the user out if they press it ***
var sideBar:SideBar = SideBar()
var homeImage = UIImage(named: "Shine Home")
var profileImage = UIImage(named: "Shine Profile")
var shareImage = UIImage(named: "Shine Share")
var aboutImage = UIImage(named: "Shine About")
var helpImage = UIImage(named: "Shine Help")
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
//setting up the menu items for the sidebar.
sideBar = SideBar(sourceView: self, menuItems: ["Home", "Profile", "Share", "About", "Help"], menuImages: [homeImage!, profileImage!, shareImage!, aboutImage!, helpImage!])
sideBar.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func sideBarDidSelectButtonAtIndex(itemIndex: Int) {
switch itemIndex {
case 0:
let vc = storyboard?.instantiateViewControllerWithIdentifier("Home") as! Home
self.navigationController?.pushViewController(vc, animated: true)
case 1:
performSegueWithIdentifier("profile", sender: self)
case 2:
performSegueWithIdentifier("share", sender: self)
case 3:
performSegueWithIdentifier("about", sender: self)
case 4:
performSegueWithIdentifier("help", sender: self)
default:
break
}
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
答案 0 :(得分:0)
这种无法识别的选择器的情况源于运行时不知道您要激活哪个特定对象。
运行时看到sideBarContainerView
对象,这对于编译器是可接受的。
问题是您的动画行为是针对视图的。你的UIViewController对象没有进入UIViews。您需要将.view
添加到sideBarContainerView
函数中的所有showSideBar
。
如果你分解了你的函数并且只使用isSideBarOpen
作为常量中if语句的bool并将其放在菜单的初始化中,那么你将立即得到Selector错误。
这只是指向错误超过上一个打印语句"I should be showing SideBar
的事实的第二种方式。
如果你这样做,那么你的菜单就会加载。到目前为止,我无法将两个菜单初始化为左右菜单。