Implement drag and drop in nsviewcontroller - objective-c

I'm trying to catch drag and drop event in nsviewcontroller, but
draggingEntered
is not called .
here is my code :
- (void)viewDidLoad {
[self.view registerForDraggedTypes:[NSArray arrayWithObjects:NSTIFFPboardType, NSFilenamesPboardType, nil]];
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender{
return NSDragOperationCopy;
}
- (BOOL)prepareForDragOperation:(id )sender {
return YES;
}
I have add custom view , but it doesn't get event too :
#implementation MyView
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
[self registerForDraggedTypes:[NSArray arrayWithObjects: NSColorPboardType, NSFilenamesPboardType, nil]];
}
return self;
}
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender {
return NSDragOperationNone;
}
#end

Related

objective c Drag And Drop IN OS X Sierra 10.12

In OS X sierra 10.12 Drag and drop is not working properly with NSTabView....
Drag and drop seems to only work in label of TabView not the entire tab ..you can see in the following project sample...download Code
OR here is code:-I have created a subClass AppMainTabSet OF NSTabView and use this class as a custom class of TabView In Interface Builder.....
#import "AppMainTabSet.h"
#implementation AppMainTabSet
- (id)initWithCoder:(NSCoder *)coder
{
/*------------------------------------------------------
Init method called for Interface Builder objects
--------------------------------------------------------*/
self=[super initWithCoder:coder];
if ( self ) {
}
return self;
}
- (void)awakeFromNib{
[self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]];
}
-(NSDragOperation) draggingEntered:(id < NSDraggingInfo >)sender
{
NSLog(#"Hello Hello....draggingEntered");
return NSDragOperationGeneric;
}
- (void)draggingExited:(id <NSDraggingInfo>)sender {
NSLog(#"**** draggingExited*****");
}
- (BOOL) prepareForDragOperation:(id <NSDraggingInfo>)sender {
NSLog(#"Hello Hello....prepareForDragOperation");
return YES;
}
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
NSLog(#"Hello Hello....performDragOperation");
return YES;
}
- (void)concludeDragOperation:(id <NSDraggingInfo>)sender {
NSLog(#"Hello Hello....concludeDragOperation");
[[NSCursor arrowCursor] push];
[self setNeedsDisplay:YES];
}
- (BOOL) processNSDraggingInfo:(id <NSDraggingInfo>)sender {
NSLog(#"Hello Hello....processNSDraggingInfo");
return YES;
}

UIImagePIckerController appears but the camera does not start

Yes, It might be a duplicate question of this. But since it didn't get an answer, I will be more specific on the case and code:
I have 3 involved UIViewControllers:
WelcomeView - the first one
TakePhotoViewController - the second one who is delegate of the OverlayviewController
OverlayViewController - custom view for the camera.
Scenario:
User enter WelcomeView and clicks on a button to be transfered with segue to TakeView.
UIImageViewController is being opened to take a photo.
The user clicks on cancel button - didCancelCamera method in TakePhotoViewController is being invoked and he returns to WelcomeView
The user leaves the app.
The user re-opens the app and perform step 1 again.
THE IMAGE PICKER IS NOT BEING OPENED. I COULD TAKE A PHOTO AND IT'S OK - BUT THE USER CAN'T SEE WHAT HE IS TAKING.
OverlayViewController.h
#interface OverlayViewController : BaseViewController<UIImagePickerControllerDelegate,UINavigationControllerDelegate>
#property (nonatomic,weak) id<OverlayViewControllerDelegate> delegate;
#property (nonatomic,retain) UIImagePickerController *imagePickerController;
#end
OverlayViewController.m:
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
self.imagePickerController = [[UIImagePickerController alloc] init];
self.imagePickerController.delegate = self;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor clearColor];
}
- (IBAction)takePicture:(id)sender {
[self.imagePickerController takePicture];
}
- (IBAction)cancelImagePicker:(id)sender {
[self.delegate didCancelCamera];
}
- (void) setupImagePicker:(UIImagePickerControllerSourceType) sourceType
{
self.imagePickerController.sourceType = sourceType;
if (sourceType == UIImagePickerControllerSourceTypeCamera)
{
self.imagePickerController.showsCameraControls = NO;
if ([[self.imagePickerController.cameraOverlayView subviews] count] ==0)
{
CGRect overlayViewFrame = self.imagePickerController.cameraOverlayView.frame;
CGRect newFrame = CGRectMake(0.0, CGRectGetHeight(overlayViewFrame)-self.view.frame.size.height-10.0, CGRectGetWidth(overlayViewFrame), self.view.frame.size.height + 10.0);
self.view.frame = newFrame;
[self.imagePickerController.cameraOverlayView addSubview:self.view];
}
}
}
- (void)finishAndUpdate
{
[NSThread detachNewThreadSelector:#selector(threadStartAnimating:) toTarget:self withObject:nil];
[self.delegate didFinishWithCamera]; // tell our delegate we are done with the camera
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[self finishAndUpdate];
}
TakePhotoViewController.h
#interface TakePhotoViewController : BaseViewController<UIImagePickerControllerDelegate,UINavigationControllerDelegate,OverlayViewControllerDelegate>
#property (nonatomic, retain) OverlayViewController *overlayViewController;
#end
TakePhotoViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
// Insert the overlay
self.overlayViewController = (OverlayViewController *)[sb instantiateViewControllerWithIdentifier:#"Overlay"];
self.overlayViewController.delegate = self;
}
- (void)viewDidUnload
{
self.overlayViewController = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (void)openImagePicker {
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){
[self showImagePicker:UIImagePickerControllerSourceTypeCamera];
}
else{
[self showImagePicker:UIImagePickerControllerSourceTypePhotoLibrary];
}
}
- (void)viewDidAppear:(BOOL)animated{
if (appDelegate.shouldOpenPicker){
[self openImagePicker];
}
}
- (void)showImagePicker:(UIImagePickerControllerSourceType)sourceType
{
if ([UIImagePickerController isSourceTypeAvailable:sourceType])
{
[self.overlayViewController setupImagePicker:sourceType];
[self presentViewController:self.overlayViewController.imagePickerController animated:YES completion:nil];
}
}
-(void)didCancelCamera{
[[self.overlayViewController.imagePickerController presentingViewController] dismissViewControllerAnimated:NO completion:^ {
[self performSegueWithIdentifier:#"fromTakeToWelcome" sender:self];
}];
}
I found the bug.
The method
-(void)didCancelCamera from TakePhotoViewController is being called when the user clicks on - (IBAction)cancelImagePicker:(id)sender in OverlayViewController.
However, somehow the code in didCancelCamera causes viewDidAppear method of TakePhotoViewController to be invoked again and reopen the image picker.
I have no idea why
[[self.overlayViewController.imagePickerController presentingViewController] dismissViewControllerAnimated:NO completion:^ {
[self performSegueWithIdentifier:#"fromTakeToWelcome" sender:self];
}];
causes the viewDidAppear method of that view (TakePhoto) being recalled again.
Hope that it will help someone

Custom field editor not drawing

I'm trying to subclass NSTokenField to intercept some of the keyboard events. I wrote subclasses for NSTokenField, NSTokenFieldCell and NSTextView. In the NSTokenField subclass I swap the regular cell with my custom cell and in the custom cell I override -(NSTextView*)fieldEditorForView:(NSView *)aControlView to provide my textview as a custom field editor. All the initialisation methods are called as expected but for some reason my custom token field is not drawn.
Here is the code for the NSTokenField subclass:
#synthesize fieldEditor = _fieldEditor;
-(JSTextView *)fieldEditor
{
if (!_fieldEditor) {
_fieldEditor = [[JSTextView alloc] init];
[_fieldEditor setFieldEditor:YES];
}
return _fieldEditor;
}
- (void)awakeFromNib {
JSTokenFieldCell *newCell = [[JSTokenFieldCell alloc] init];
[self setCell:newCell];
}
+ (Class) cellClass
{
return [JSTokenFieldCell class];
}
- (id)initWithFrame:(NSRect)frameRect
{
self = [super initWithFrame:frameRect];
if (self) {
JSTokenFieldCell *newCell = [[JSTokenFieldCell alloc] init];
[self setCell:newCell];
}
return self;
}
-(id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
JSTokenFieldCell *newCell = [[JSTokenFieldCell alloc] initWithCoder:aDecoder];
[self setCell:newCell];
}
return self;
}
And here is the code for the subclass of NSTokenFieldCell:
-(NSTextView*)fieldEditorForView:(NSView *)aControlView
{
if ([aControlView isKindOfClass:[JSTokenField class]]) {
JSTokenField *tokenField = (JSTokenField *)aControlView;
return tokenField.fieldEditor;
}
return nil;
}
- (id)initWithCoder:(NSCoder *)decoder
{
return [super initWithCoder:decoder];
}
- (id)initTextCell:(NSString *)aString
{
return [super initTextCell:aString];
}
- (id)initImageCell:(NSImage *)anImage
{
return [super initImageCell:anImage];
}
Addition
After further digging I found this post which says that the only way to have an NSTokenField with a custom text view is by overriding private methods. Is it true? If so, is there any other way I can intercept keyboard events without subclassing NSTextView?

Subclass of UIView. How to add through Interface Builder?

I have a subclass of UITextField and want to be able to add it to the view in IB. What I did is added UITextField and changed its class to my subclass in Identity tab of Inspector. But I can only see UITextField on the view.
Code:
#interface ExtendedTextField : UITextField {
}
//implementation
#implementation ExtendedTextField
- (void)baseInit
{
UIImage * curImage = [UIImage imageNamed:#"tfbg.png"];
[self baseInitWithImage : curImage];
}
- (void)baseInitWithImage : (UIImage *) aImage
{
aImage = [aImage stretchableImageWithLeftCapWidth:29 topCapHeight:29];
self.background = aImage;
self.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
UIView * curLeftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, self.frame.size.height)];
self.leftView = curLeftView;
self.rightView = curLeftView;
[curLeftView release];
self.leftViewMode = UITextFieldViewModeAlways;
self.rightViewMode = UITextFieldViewModeAlways;
[self setTextColor:[UIColor greenColor]];
}
- (void)awakeFromNib
{
[super awakeFromNib];
[self baseInit];
}
/*
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
[self baseInit];
}
return self;
}
*/
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self)
{
[self baseInit];
}
return self;
}
- (id)initWithFrame:(CGRect)frame withImage:(UIImage*)aImage
{
self = [super initWithFrame:frame];
if (self) {
[self baseInitWithImage : aImage];
}
return self;
}
- (void)dealloc {
[super dealloc];
}
#end
EDIT: I noticed several things:
-- if I put [super initWithFrame:...] instead of [super initWithCoder:...] inside
(id)initWithCoder:(NSCoder *)aDecoder
it works well.
-- Now I am using awakefromnib instead of initwithcoder and the only thing that get changed in textfield is textColor.
Could someone explain why so?
Solution I needed to set border style to none. BS overlayed bg image.
While showing your .xib in Xcode, reveal the right pane, select your view and in the third tab, change Classto whatever you want it to be.

NSView mouseExited

I have an NSView and basically, even when my mouse doesn't leave the defined frame, just moves within it, mouseExited function is called. Is this how is it suppose to be or am I doing something wrong? There are several subviews of this NSView and it's custom and here's the code for it:
- (id)initWithDelegate:(id)del {
if (self = [super init]) {
[del retain];
delegate = del;
}
return self;
}
- (void)dealloc {
[delegate release];
[super dealloc];
}
- (void)viewDidMoveToWindow {
[self addTrackingRect:[self bounds]
owner:self
userData:nil
assumeInside:NO];
}
- (void)mouseEntered:(NSEvent *)theEvent {
[delegate mouseEntered];
}
- (void)mouseExited:(NSEvent *)theEvent {
NSLog(#"mouse exited");
[delegate mouseExited];
}
- (void)mouseDown:(NSEvent *)theEvent {
[delegate mouseDown];
}
- (NSView *)hitTest:(NSPoint)aPoint {
return self;
}
Thanks.
I figuered it out. After adding a tracking area, i was changing the frame of my view so I needed to recalculate the tracking area. Found this method that will automatically be called whenever tracking area needs to be updated:
- (void)updateTrackingAreas {
Just simply recalculate your tracking area here.