我正在socket.io我的swift ios应用程序中实现.
目前在几个面板上我正在监听服务器并等待收到的消息.我这样做是通过调用getChatMessage每个面板中的函数来实现的:
func getChatMessage(){
SocketIOManager.sharedInstance.getChatMessage { (messageInfo) -> Void in
dispatch_async(dispatch_get_main_queue(), { () -> Void in
//do sth depending on which panel user is
})
}
}
Run Code Online (Sandbox Code Playgroud)
但是我注意到这是一个错误的方法,我需要更改它 - 现在我想开始只收听一次传入消息,当任何消息到来时 - 将此消息传递给任何监听它的面板.
所以我想通过NSNotificationCenter传递传入的消息.到目前为止,我能够传递发生的事情的信息,但不能传递数据本身.我是这样做的:
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ViewController.showSpinningWheel(_:)), name: showSpinner, object: nil)
Run Code Online (Sandbox Code Playgroud)
然后我有一个叫做的函数:
func showSpinningWheel(notification: NSNotification) {
}
Run Code Online (Sandbox Code Playgroud)
任何时候我想打电话给我:
NSNotificationCenter.defaultCenter().postNotificationName(hideSpinner, object: self)
Run Code Online (Sandbox Code Playgroud)
那么如何传递对象messageInfo并将其包含在被调用的函数中?
我正在学习Swift 3,我正在尝试使用它NSNotificationCenter.这是我的代码:
func savePost(){
let postData = NSKeyedArchiver.archivedData(withRootObject: _loadedpost)
UserDefaults.standard().object(forKey: KEY_POST)
}
func loadPost(){
if let postData = UserDefaults.standard().object(forKey: KEY_POST) as? NSData{
if let postArray = NSKeyedUnarchiver.unarchiveObject(with: postData as Data) as? [Post]{
_loadedpost = postArray
}
}
//codeerror
NotificationCenter.default().post(NSNotification(name: "loadedPost" as NSNotification.Name, object: nil) as Notification)
}
Run Code Online (Sandbox Code Playgroud)
这是观察者:
override func viewDidLoad() {
super.viewDidLoad()
//codeerorr
NotificationCenter.default().addObserver(self, selector: Selector(("onPostLoaded")), name: "loadedPost", object: nil)
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
Run Code Online (Sandbox Code Playgroud)
它总是给我错误"信号SIGBRT".当我尝试在观察者中更改名称时,这不是错误,但显然它没有显示任何内容.我该如何解决?
我按如下方式设置了一个观察者,其中包括以下logYes()功能:
class SplashPageVC: UIViewController {
func logYes() {
println("Yes");
}
override func viewDidLoad() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "logYes:", name: "userValid", object: nil)
}
}
Run Code Online (Sandbox Code Playgroud)
我已经将以下IBAction连接到一个按钮:
class LoginVC: UIViewController {
@IBAction func loginSubmitted(sender : AnyObject) {
NSNotificationCenter.defaultCenter().postNotificationName("userValid", object: nil)
}
}
Run Code Online (Sandbox Code Playgroud)
点击按钮时出现以下错误:
[_TtC13Explorer12SplashPageVC self.logYes:]: unrecognized selector sent to instance
Run Code Online (Sandbox Code Playgroud)
我尝试了一堆不同的选择器,没有运气:
logYes
logYes:
logYes()
logYes():
Run Code Online (Sandbox Code Playgroud)
我没有想法.任何见解?tyvm :)
参考文献:
在postNotificationName中没有发送
NSNotification :在Swift 中的swift委托中称为NSNotificationCenter addObserver
?
我使用addObserverAPI来接收通知:
NSNotificationCenter.defaultCenter().addObserver(self, selector: "methodOFReceivedNotication:", name:"NotificationIdentifier", object: nil)
Run Code Online (Sandbox Code Playgroud)
我的方法是:
func methodOFReceivedNotication(notification: NSNotification){
//Action take on Notification
}
Run Code Online (Sandbox Code Playgroud)
是的,它有效!但是当我将方法更改methodOFReceivedNotication为私有时:
private func methodOFReceivedNotication(notification: NSNotification){
//Action take on Notification
}
Run Code Online (Sandbox Code Playgroud)
xCode发给我一个错误: unrecognized selector sent to instance
如何在目标时调用私有方法self?我不想将methodOFReceivedNotication方法暴露给任何其他人.
我有一个uitabbarcontroller,它包含多个选项卡和viewControllers.我试图循环通过视图控制器找到正确的一个并调用方法.但我得到的视图控制器的类型,每次我通过循环是一个UINavigationController.那么我怎样才能简单地访问tabBar中的视图控制器?
for (UIViewController *v in self.tabBar.viewControllers)
{
if ([v isKindOfClass:[MyViewController class]])
{
MyViewController *myViewController = v;
[v doSomething];
}
}
Run Code Online (Sandbox Code Playgroud) iphone uitabbarcontroller uiviewcontroller uinavigationcontroller
我正在使用Swift 3.1和Xcode 8.3.3编写程序.我想创建一个类,负责在键盘出现和消失时移动整个视图.但是我遇到了使用string中的参数创建自定义Selector的困难.要显示或隐藏键盘我们需要功能:
func keyboardWillShow(notification: Notification) {
//Code moving view when keyboard appears
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试创建一个这样的选择器:
let selector = Selector(("keyboardWillShow")
NotificationCenter.default.addObserver(view, selector: selector, name: .UIKeyboardWillShow, object: anyView.view.window)
Run Code Online (Sandbox Code Playgroud)
它正在编译,但是当键盘出现时,它会崩溃.因为它是独立的类我不能使用这种结构:
#selector(keyboardWillShow)
Run Code Online (Sandbox Code Playgroud)
因为它将Swift函数转换为Objective-C函数(添加@objc).所以问题是:如何用参数字符串创建一个Selector表单?
PS我可以把整个代码放在那里,但我不想要问题非常大,所以我会编辑问题,如果有人问...
我正在尝试在我的iOS 8 Swift应用程序中实现一个简单的键盘观察器,但它确实不起作用.这是我目前正在使用的代码:
override func viewDidAppear(animated: Bool) {
NSNotificationCenter().addObserver(self, selector: Selector(keyboardWillAppear()), name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter().addObserver(self, selector: Selector(keyboardWillHide()), name: UIKeyboardWillHideNotification, object: nil)
}
override func viewDidDisappear(animated: Bool) {
NSNotificationCenter().removeObserver(self)
}
func keyboardWillAppear() {
logoHeightConstraint.constant = 128.0
}
func keyboardWillHide() {
logoHeightConstraint.constant = 256.0
}
Run Code Online (Sandbox Code Playgroud)
奇怪的是,在启动应用程序后,两个对键盘作出反应的功能都会被调用.当我进入或离开文本字段时没有任何反应.我究竟做错了什么?顺便说一下:改变约束是改变图像大小的最佳解决方案吗?
我真的很感谢你的帮助!
在XCTest with swift中,您可以在需要它的测试函数中定义模拟对象.就像这样
func testFunction(){
class mockClass: AnyObject{
func aFunction(){
}
}
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用这些模拟对象来测试另一个函数在给定某个条件的情况下发出正确的通知(在我的情况下,成功通知是用对象的204状态代码广播的.
我遇到的问题是我得到一个"无法识别的选择器"运行时错误,即使该deletedSuccess()函数显然存在/
下面是一些代码转储
func testDelete(){
let expectation = expectationWithDescription("Post was deleted")
class MockReciever : AnyObject {
func deleteSuccess(){
println("delete successfull")
expectation.fulfill()
}
}
let mockReciever = MockReciever()
NSNotificationCenter.defaultCenter().addObserver(mockReciever, selector: "deleteSuccess", name: PostDeletedNotification, object: post)
let response = NSHTTPURLResponse(URL: NSURL(), statusCode: 204, HTTPVersion: nil, headerFields: nil)
let request = NSURLRequest()
post.deleteCompletion(request, response: response, data: nil, error: nil)
waitForExpectationsWithTimeout(30, handler: { (error) -> Void in
if error …Run Code Online (Sandbox Code Playgroud) 经过一段时间的努力,在寻找解决方案几个小时之后,我认为是时候问了。
我有一个由自定义UITableViewCells填充的表格视图,当前当您点击一个单元格时,它将带您到详细视图。
在自定义单元中有一个图像,我希望用户能够点击该图像并选择显示该图像的弹出式VC。
我遇到的麻烦是在点击图像时创建序列。
在自定义单元格的文件中,我在图像(pTap)上设置了轻击手势识别器:
override func awakeFromNib() {
super.awakeFromNib()
let tap = UITapGestureRecognizer(target: self, action: #selector(PostCell.voteTapped(_:)))
let ptap = UITapGestureRecognizer(target: self, action: #selector(PostCell.imageTapped(_:)))
tap.numberOfTapsRequired = 1
ptap.numberOfTapsRequired = 1
voteImage.addGestureRecognizer(tap)
voteImage.userInteractionEnabled = true
featuredImg.addGestureRecognizer(ptap)
featuredImg.userInteractionEnabled = true
}
Run Code Online (Sandbox Code Playgroud)
我还在自定义单元文件中有一个用于点击的功能:
func imageTapped(sender: UIGestureRecognizer) {
print("image tapped")
}
Run Code Online (Sandbox Code Playgroud)
在我的视图控制器文件中,我在索引路径的选择行中添加了segue:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let post: Post!
if inSearchMode {
post = filteredVenues[indexPath.row]
} else {
post = posts[indexPath.row]
}
print(post?.venueName)
performSegueWithIdentifier("imageTapped", sender: nil)
performSegueWithIdentifier("DetailsVC", …Run Code Online (Sandbox Code Playgroud) 我有一个复杂的视图类,
class Snap:UIViewController, UIScrollViewDelegate
{
}
Run Code Online (Sandbox Code Playgroud)
最终的结果是,用户可以选择一种颜色......
protocol SnapProtocol:class
{
func colorPicked(i:Int)
}
class Snap:UIViewController, UIScrollViewDelegate
{
someDelegate.colorPicked(blah)
}
Run Code Online (Sandbox Code Playgroud)
那么谁将会处理它.
让我们说你肯定知道响应者链上有什么东西,甚至走过容器视图,这是一个SnapProtocol.如果是这样,您可以使用这个可爱的代码来调用它
var r : UIResponder = self
repeat { r = r.nextResponder()! } while !(r is SnapProtocol)
(r as! SnapProtocol).colorPicked(x)
Run Code Online (Sandbox Code Playgroud)
如果您愿意,可以使用此最佳扩展名
public extension UIResponder // walk up responder chain
{
public func next<T>() -> T?
{
guard let responder = self.nextResponder()
else { return nil }
return (responder as? T) ?? responder.next()
}
} …Run Code Online (Sandbox Code Playgroud)