objective c Drag And Drop IN OS X Sierra 10.12 - objective-c

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;
}

Related

How to get contents of a NSTextFieldCell in a cell-based outline when the user quits while editing

The previous version of this question was closed because the moderator did not recognize that this is a cell-based Outline not a view-based outline. The answer the moderator suggested does not work for a cell-based outline.
The question as previously asked was:
I have a cell-based NSOutlineView. How do I get the contents of the NSTextFieldCell when the user Quits the app while editing that cell. Currently, attributedStringValue returns the contents before editing began.
As requested in the comments, here is a NSViewController.h and .m . It references a storyboard with two outlets: outlineView and cellOutlet as shown in viewController.h.
ViewController.h
#import <Cocoa/Cocoa.h>
#interface ViewController : NSViewController <NSOutlineViewDataSource,NSOutlineViewDelegate, NSTextStorageDelegate, NSTextViewDelegate, NSWindowDelegate, NSTextFinderClient,NSTextFieldDelegate,NSSearchFieldDelegate>
#property (weak) IBOutlet NSOutlineView *outlineView;
#property (weak) IBOutlet NSTextFieldCell *cellOutlet;
#property(nonatomic,strong)NSMutableAttributedString* string;
#end
and ViewController.m
#import "ViewController.h"
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(void)viewWillAppear
{
self.outlineView.dataSource = self;
self.outlineView.delegate = self;
self.outlineView.window.delegate = self;
self.string = [[NSMutableAttributedString alloc] initWithString:#"TEST"];
}
- (void)setRepresentedObject:(id)representedObject {
[super setRepresentedObject:representedObject];
}
-(BOOL)windowShouldClose:(NSWindow *)sender
{
[self.view.window makeFirstResponder:nil];
BOOL response = [sender makeFirstResponder:sender];
NSMutableAttributedString* changedText = [[_cellOutlet attributedStringValue] mutableCopy];
NSLog(#"On Quit value was: %#", changedText);
return response;
}
-(id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item
{
NSMutableAttributedString* string = [[NSMutableAttributedString alloc] initWithString:#"Outline Item"];
return string;
}
-(BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
{
return NO;
}
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{
{
return _string;
}
}
- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
{
if (!item)
{
return 1;
}
else
{
return 0;
}
}
- (void)outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{
_string = object;
NSLog(#"Changed Value: %#",_string);
}
#end
Implement windowShouldClose in the window delegate class and call [window makeFirstResponder:nil].
- (BOOL)windowShouldClose:(NSWindow *)sender {
return [sender makeFirstResponder:nil];
}
Implement applicationShouldTerminate in the application delegate class and test if the key window should close.
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
NSWindow *window = [sender keyWindow];
if (![window.delegate windowShouldClose:window])
return NSTerminateCancel;
return NSTerminateNow;
}
Set "Application can be killed immediately when user is shutting down or logging out" to NO in info.plist.

Implement drag and drop in nsviewcontroller

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

iOS8 Modal ViewController not fires shouldAutoRotate.

I have a parentViewController that calls a modal ViewController with Delegate UITableViewController. The problem is that I do not have navigation stack to get the value from the parent's shouldAUtoRotate.
Since the shouldAutorotate never fired it gets it from a main controller where return NO and this cannot be changed. Is there a way to manipulate the modal controller to get the proper shouldAutorotate set to YES?
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[self.pv dismiss:YES];
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
if(UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) {
//[self fullScreenAction:nil];
} else {
// [self exitFullScreenAction:nil];
}
}
}
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
return UIInterfaceOrientationMaskAll;
} else {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
}
//ios >=6
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ||
(interfaceOrientation == UIInterfaceOrientationPortrait) ||
(interfaceOrientation == UIInterfaceOrientationLandscapeLeft) ||
(interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
I managed to solve my problem although is not the best solution, maybe for some will be useful.
So i create a new Category Controller in order to use it to set manually the Rotation calls.
.m
#import "UINavigationController+AutoRotate.h"
#implementation UINavigationController (AutoRotate)
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationMaskAll;
}
#end
and .h
#import <UIKit/UIKit.h>
#interface UINavigationController (AutoRotate)
- (BOOL)shouldAutorotate;
- (NSUInteger)supportedInterfaceOrientations;
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation;
#end
And then the Modal was working as it should without a navigation controller.

Maintaining reference to UITextField "text" field

Problem:
I am trying to create a custom UITextField class "UIValidatedTextField" which allows one to set certain rules as to whether input is valid. For example, you can set a regex parameter to ensure that input is of a specific format, i.e. a password, email address, etc...
Another ability of this is to specify and set a parameter that references another UITextField and ensures that the input matches the input from that other UITextField.
The issue I am having here, is that I am setting this reference to another UITextField. However, when I access its "text" field I find that there is nothing in the text field even when I type something into it.
I have provided related code below:
#import "UIRegisterViewController.h"
#import "UIRegisterViewCell.h"
#import "UIValidatedTextField.h"
#import "NSConstants.h"
#interface UIRegisterViewController ()
#end
#implementation UIRegisterViewController
- (void)viewDidLoad {
[super viewDidLoad];
_tableView.delegate = self;
_tableView.dataSource = self;
_tableItems = #[#"name", #"email", #"netId", #"username", #"password", #"confirmPassword"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_tableItems count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *cellIdentifier = [_tableItems objectAtIndex:indexPath.row];
UIRegisterViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
if ([cellIdentifier isEqualToString:#"email"]) {
[cell.textField setRegex:VALID_DUKE_EMAIL_REGEX];
} else if ([cellIdentifier isEqualToString:#"netId"]) {
//Validation?
} else if ([cellIdentifier isEqualToString:#"username"]) {
//Validation?
//THIS IS THE CELL THAT I WANT TO COMPARE INPUT TO
} else if ([cellIdentifier isEqualToString:#"password"]) {
[cell.textField setRegex:VALID_PASSWORD_REGEX];
//SETTING THE TEXT FIELD IN QUESTION HERE...
} else if ([cellIdentifier isEqualToString:#"confirmPassword"]) {
[cell.textField setRegex:VALID_PASSWORD_REGEX];
NSIndexPath *index = [NSIndexPath indexPathForRow:4 inSection:0];
UIRegisterViewCell *confirm =(UIRegisterViewCell *)[self tableView:_tableView cellForRowAtIndexPath:index];
[cell.textField setConfirm:confirm.textField];
}
cell.textField.delegate = self;
return cell;
}
#pragma mark - Text Field Delegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
#end
Note that the textFields are UIValidatedTextFields - a custom class provided below:
#import "UIValidatedTextField.h"
#import "NSArgumentValidator.h"
#implementation UIValidatedTextField
- (id) initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self initialize];
}
return self;
}
- (id)initialize {
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(textFieldDidChange:)
name:UITextFieldTextDidChangeNotification object:self];
[self validate]; //Validate in case editing began before observer was set.
}
return self;
}
- (void) setOptional:(BOOL)isOptional {
_isOptional = isOptional;
}
- (BOOL) isOptional {
return _isOptional;
}
- (void) setRegex:(NSString *)regex {
_regex = regex;
}
//SET THE TEXT FIELD TO COMPARE INPUT AGAINST HERE.
- (void) setConfirm:(UITextField *)confirm {
_confirm = confirm;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(textFieldDidChange:)
name:UITextFieldTextDidChangeNotification object:_confirm];
[self validate]; //Validate in case editing on confirm began before observer was set.
}
- (void) setQuery:(NSString *)query {
_query = query;
}
- (void) textFieldDidChange:(NSNotification *)notification {
NSLog(#"UPDATE");
_isValid = [self validate];
[self showInputValidation];
}
- (BOOL) validateRegex {
if (_regex.length == 0) {
return true;
}
return [NSArgumentValidator isValid:self.text withRegex:_regex];
}
- (BOOL) validateConfirm {
// NSLog(#"%# : %#", [_confirm text], self.text);
if (_confirm == NULL) {
//NSLog(#"IS NULL");
return true;
}
return [self.text isEqualToString:_confirm.text];
}
- (BOOL) validateQuery {
return true;
}
- (BOOL) validate {
_isValid = (self.text == 0 && _isOptional) || ((self.text != 0) && [self validateRegex] && [self validateConfirm] && [self validateQuery]);
return _isValid;
}
//IF ANYONE HAS A SOLUTION AS TO HOW TO MAKE CHANGING BORDER COLOR CHANGE THE COLOR ALONG THE ROUNDED BORDER THAT IS PRESENT AS OPPOSED TO A RECTANGULAR BORDER LET ME KNOW.
- (void) showInputValidation {
self.layer.borderWidth = 1.0;
if (self.text.length == 0) {
self.layer.borderColor = [[UIColor blackColor] CGColor];
} else if (_isValid) {
self.layer.borderColor = [[UIColor greenColor] CGColor];
} else {
self.layer.borderColor = [[UIColor redColor] CGColor];
}
}
- (void) finalize {
[super finalize];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UITextFieldTextDidChangeNotification object:self];
if (_confirm != NULL) {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UITextFieldTextDidChangeNotification object:_confirm];
}
}
#end
Thanks for the help!
One glaring bug in this code is that you're setting the regex in cellForRowAtIndexPath:, even though all cell are reusing the same cell object. cellForRowAtIndexPath: should be used only to set cell content, like text and color. Instead, create an IBOutlet to the validating text fields and add their regexes in viewDidLoad. Better yet, scrap the custom subclass entirely and instead run your regex validation whenever one of the relevant text fields fires off an event when editing is finished.

Shake gesture and firstResponder

I'm trying to get shake gesture to work. Here is some code
In my implementation file
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
if(event.type == UIEventSubtypeMotionShake)
{
NSLog(#"Shake gesture detected");
}
}
- (BOOL)canBecomeFirstResponder
{
return YES;
}
I read that in order to make shake gesture to work UIView should be the firstResponder. This is why I added that code in implementation
if(self.view.isFirstResponder)
{
NSLog(#"first");
}
else
{
NSLog(#"no");
}
- (void)viewDidAppear {
[self becomeFirstResponder];
}
When I run the app the output of NSLog is NO. What I miss ? And how to get shake gesture to work
I guess you're doing this in your UIViewController? That's not correct … You have to subclass UIView like this:
ShakeView.h:
//
// ShakeView.h
//
#import <UIKit/UIKit.h>
#interface ShakeView : UIView {
}
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event;
- (BOOL)canBecomeFirstResponder;
#end
ShakeView.m:
//
// ShakeView.m
//
#import "ShakeView.h"
#implementation ShakeView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
}
return self;
}
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
if ( event.subtype == UIEventSubtypeMotionShake ) {
}
if ( [super respondsToSelector:#selector(motionEnded:withEvent:)] ) {
[super motionEnded:motion withEvent:event];
}
}
- (BOOL)canBecomeFirstResponder
{
return YES;
}
#end
Then use ShakeView instead of your "normal" UIView and implement this in your UIViewController:
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
NSLog(#"Shake happend …");
}
- (void)viewDidAppear:(BOOL)animated
{
[self.view becomeFirstResponder];
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[self.view resignFirstResponder];
[super viewWillDisappear:animated];
}
That's it. Hope it helps :)