using UIGestureRecognizer occur some problems - uigesturerecognizer

let recognizer: UIGestureRecognizer
for recognizer in self.gestureRecognizers! {
if recognizer is DollarPGestureRecognizer {
recognizer.recognize()
self.clearAll()
}
}
how is if recognizer is DollarPGestureRecognizer means?
and also , recognize() function is declared in DollarPGesturRecognizer.h like
#interface DollarPGestureRecognizer : UIGestureRecognizer {
DollarP *dollarP;
NSMutableDictionary *currentTouches;
NSMutableArray *currentPoints;
NSMutableArray *points;
int strokeId;
}
- (void)recognize;
#end
how can i successfully do the recognize function?

Little unclear as to what you are asking but here goes:
First Question Answer) recognizer is DollarPGestureRecognizer returns true if recognizer is an instance of the DollarPGestureRecognizer class.
Second Question Answer) In order to use the DollarPGestureRecognizer you need to instantiate an instance of one and then add is as a gesture recognizer to the view where you want it to be active. So you could do something like this (as a rough example):
let dollarRecognizer = DollarPGestureRecognizer(target:self, action:"handleDollarGesture:"
myView.addGestureRecognizer(dollarRecognizer)
then define the handler in that target class (in this case self)
func handleDollarGesture(recognizer: DollarPGestureRecognizer) {
//Do Something
}
Side Note) If you want some help implementing your own custom UIGestureRecognizer you should look at the following article:
http://www.raywenderlich.com/104744/uigesturerecognizer-tutorial-creating-custom-recognizers

Related

Handling NSMenuDelegate menuWillOpen for changing targets

There are lots of related answers about using menuWillOpen. They all explain that one needs to set the menu's delegate first.
This is easy when I have just one target, like a Preferences window or the main application.
But what if I have a document based app, and I need to have the active document handle menuWillOpen? Then the delegate isn't a constant any more.
What's the proper way to handle this? Do I have to set the delegate to a single object (like the AppDelegate) and then forward the call to the active view controller (but how is that done correctly)? Or is there some other elegant way?
I came up with this code which appears to work:
// This is in my AppDelegate class, and the NSMenu's delegate points to it:
- (void)menuWillOpen:(NSMenu *)menu {
// Forward to active document controller
NSWindow *mainWindow = [NSApplication sharedApplication].mainWindow;
NSResponder *r = mainWindow.firstResponder;
while (r) {
if ([r respondsToSelector:_cmd]) {
[(id<NSMenuDelegate>)r menuWillOpen:menu];
return;
}
r = r.nextResponder;
}
}
It assumes that a controller down the responder chain implements menuWillOpen:

NSView with a KVC property in Swift

I have a custom NSView class defined as:
class MyView: NSView
{
var someText: NSString
override func didChangeValueForKey(key: String)
{
println( key )
super.didChangeValueForKey( key )
}
// other stuff
}
What I want to be able to do is from outside of this class change the value of someText and have didChangeValueForKey notice that someText has changed so I can, for example, set needsDisplay to true for the view and do some other work.
How an I do this?
Are you sure you need KVC for this? KVC works fine in Swift, but there’s an easier way:
var SomeText: NSString {
didSet {
// do some work every time SomeText is set
}
}
There is no KVC mechanism for this because this isn't what KVC is for.
In Objective-C, you would implement the setter explicitly (or override if the property is originally from a superclass) and do your work there.
In Swift, the proper approach is the didSet mechanism.
didChangeValueForKey() is not part of KVC, it's part of KVO (Key-Value Observing). It is not intended to be overridden. It's intended to be called when one is implementing manual change notification (as a pair with willChangeValueForKey()).
More importantly, though, there's no reason to believe that it will be called at all for a property which is not being observed by anything. KVO swizzles the class in order to hook into the setters and other mutating accessors for those properties which are actually being observed. When such a property is changed (and supports automatic change notification), KVO calls willChangeValueForKey() and didChangeValueForKey() automatically. But for non-observed properties, those methods are not called.
Finally, in some cases, such as the indexed collection mutation accessors, KVO will use different change notification methods, such as willChange(_:valuesAtIndexes:forKey:) and didChange(_:valuesAtIndexes:forKey:).
If you really don't want to use didSet for some reason, you would use KVO to observe self for changes in the someText property and handle changes in observeValueForKeyPath(_:ofObject:change:context:). But this is a bad, clumsy, error-prone, inefficient way of doing a simple thing.
KVO and didSet are not mutually exclusive:
import Foundation
class C: NSObject {
dynamic var someText: String = "" {
didSet {
print("changed to \(someText)")
}
}
}
let c = C()
c.someText = "hi" // prints "changed to hi"
class Observer: NSObject {
init(_ c: C) {
super.init()
c.addObserver(self, forKeyPath: "someText", options: [], context: nil)
}
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
print("observed change to \(object!.valueForKeyPath(keyPath!))")
}
}
let o = Observer(c)
c.someText = "test" // prints "changed to test" and "observed change to test"
I would add to Jaanus's answer that to make the property KVC compliant, you should declare it as dynamic var someText: NSString.
But if you don't need all the bells and whistles oh KVC, didSet is the way to go.
Update
As for didChangeValueForKey: – it is intended for the opposite, for you to notify value for key has changed (if it is not due to one of the cases covered by Foundation). You should use addObserver(_:forKeyPath:options:context:) and override observeValueForKeyPath(_:ofObject:change:context:) to be notified of changes.
Alternatively you can use one of many 3rd party solutions such as ReactiveCococa or Facebook's KVOController

NSWindowController in Swift. Subclassing and initializing with Nib

In a test Swift project, I am subclassing NSWindowController. My NSWindowController subclass is designed to work with a particular Nib file. It is desirable, then, that when my window controller is initialized, the nib file is automatically loaded by the window controller instance. In Objective-C, this was achieved by doing:
#implementation MyWindowController
- (id)init {
self = [super initWithWindowNibName:"MyWindowNib"]
if (self) {
// whatever
}
return self
}
#end
Now, in Swift this is not possible: init() cannot call super.init(windowNibName:), because the later is declared not as a designated initializer, but as a convenience one by NSWindowController.
How can this be done in Swift? I don't see a strightforward way of doing it.
P.S.: I have seen other questions regarding this topic, but, as long as I've been able to understand, the solutions all point to initialize the Window Controller by calling init(windowNibName:). Please note that this is not the desired beheaviour. The Window Controller should be initialized with init(), and it should be the Window Controller itself who "picks up" its Nib file and loads it.
If you use the init() just to call super.init(windowNibName:), you could instead just override the windowNibName variable.
override var windowNibName: String {
get {
return "MyWindowNib"
}
}
Then there should be no need to mess with the initializers.
You can create your own convenience initializer instead:
override convenience init() {
self.init(windowNibName: "MyWindowNib")
}
You should instead opt in to replacing all designated initializers in your subclass, simply delegating to super where appropriate. Confer https://stackoverflow.com/a/24220904/1460929

Monotouch: understand the delegate mechanism pattern

I didin't completely understand the delegate mechanism in monotouch. Can anyone help me to understand this concept?
The question is simple. I'll try to map what I've done in Objective C in Monotouch.
For example, suppose I've creating a UIPopoverController in Objective C inside MyController. In Objective C the code is the following:
#interface MyController : UIViewController <UIPopoverControllerDelegate> {
// ...
}
// ...
#end
Inside MyController I can istantiate a UIPopoverController like the following:
UIPopoverController *popover = // ...
popover.delegate = self;
and finally methods used in the delegate.
So, what about Monotouch?
Through this code I can istantiate the UIPopoverController inside MyController class that extends UIViewController inside a specific TouchUpInside event handler:
popover = new UIPopoverController(new CustomController());
popover.PopoverContentSize = new SizeF(200f, 200f);
popover.PresentFromRect(button.Frame, containerForButtonView, UIPopoverArrowDirection.Left, true);
P.S. An important aspect is to put popover reference as a member class and not as a local variable inside the handler because the monotouch GC works well!!!
Thank you in advance.
This really has more to do with C# than MonoTouch itself. In MonoTouch, UIPopoverControllerDelegate is a class, and C# doesn't allow multiple inheritance, so you can't translate code one to one with Obj-C. There's an easier way out though (code below compiles, but obviously doesn't work):
public class MyController: UIViewController {
public void mymethod(){
var popover = new UIPopoverController();
popover.DidDismiss += HandlePopoverDidDismiss;
popover.PopoverContentSize = new SizeF(200f, 200f);
popover.PresentFromRect(button.Frame, containerForButtonView, UIPopoverArrowDirection.Left, true);
}
void HandlePopoverDidDismiss (object sender, EventArgs e)
{
Console.WriteLine("Working!");
}
}
}
As you can see, you can add an event handler to to the DidDismiss event in the popover, which will do what you want. In general, all events that in Obj-C are handled by the delegate in all controls can be used this way. You can also write the method inline, like this:
popover.DidDismiss += delegate {
//dosomething
};
Hope this is what you're looking for.
This doesn't answer your question specific to your UIPopovercontroller I think you will find this link from the Monotouch Docs useful. It explains the differences between Objective-C delegates and C# delegates with relation to Monotouch. With regards to your specific problem, I havent got time to whip up a quick test case to understand it fully but figured I'd post that link so you've got something to read in the mean time!

How to bind a control to a singleton in Cocoa?

I have a singleton in my FTP app designed to store all of the types of servers that the app can handle, such as FTP or Amazon S3. These types are plugins which are located in the app bundle. Their path is located by applicationWillFinishLoading: and sent to the addServerType: method inside the singleton to be loaded and stored in an NSMutableDictionary.
My question is this:
How do I bind an NSDictionaryController to the dictionary inside the singleton instance? Can it be done in IB, or do I have to do it in code? I need to be able to display the dictionary's keys in an NSPopupButton so the user can select a server type.
Thanks in advance!
SphereCat1
I found / made up the answer to this: I simply override the init method so when it's called from the XIB file, it still returns the singleton. I then provide a method named realInit to do an actual initialization the first time init is called.
Code:
-(id)init
{
#synchronized(self)
{
if (_sharedInstance == nil)
{
_sharedInstance = [[VayprServerTypes alloc] realInit];
}
}
[self release];
return _sharedInstance;
}
-(id)realInit
{
if (self = [super init])
{
serverTypesArray = [[NSMutableArray alloc] init];
}
return self;
}
EDIT: Of course you'll need to define _sharedInstance as a static variable at the top of your class implementation:
static ClassTypeGoesHere *_sharedInstance;
ALSO EDIT: Since you now know for sure that your init method will be called at least once, you can go ahead and replace your normal singleton sharedInstance method with this:
+(ClassTypeGoesHere *)sharedInstance
{
return _sharedInstance;
}
If anyone sees any obvious problems with this design, please let me know!
SphereCat1

Resources