I have coded drag & drop for the NSImageView, and I set the NSImageView as the PDF/image files drop zone. But I found once the files dropped, the NSImageView shows the dropped file content and image. How can I avoid that? I want NSImageView shows the default image I set when the application launch. I also tried to add this code but doesn't work:
[imgView setImage:[NSImage imageNamed:#"default.jpg"]];
after you process data, you can clear NSDraggingInfo like this:
override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
// process your data form NSDraggingInfo
// and clearContents
sender.draggingPasteboard().clearContents()
return true
}
Create a subclass of ImageView. Remove the drawRect:(NSRect)rect method if there is in its implementation file. You won't need it.
Click on the identity inspector tab of the sidebar to the right. Then enter the name of your imageView subclass after selecting an imageView control, which you have already done, probably.
Click on the attributes inspector tab of the sidebar. Select your imageView control and then enter the name of the background image in the top combobox.
Subclass NSImageView and implement following method.
Setting new image with draggingInfo is done from concludeDragOperation by default.
override func concludeDragOperation(_ sender: NSDraggingInfo?) {
return
}
Related
I have a UICollectionView that scrolls vertically with about 15 cells. Then directly below this UICollectionView I have a UIButton. I can successfully focus the UIButton, but only if I scroll down through all of the UICollectionViewCells. I am wondering if it is possible to transition focus from the first UICollectionViewCell down to the UIButton without having to scroll through all of the UICollectionView's items?
A diagram of the desired behavior:
If you really want that behavior then you can return the button in the following function,
override var preferredFocusEnvironments: [UIFocusEnvironment]
And then subclass the following function,
override func shouldUpdateFocus(in context: UIFocusUpdateContext) -> Bool {
and return false when the focus is about to go to second cell and before returning call setNeedsFocusUpdate() which will make system check for preferred focus element and moves the focus to the button.
Really wonder why you are after this behavior 🤔, but its doable.
Did you try with canFocusAtItem to all other collectionView cells to false.
Then directly the focus will go the UIButton.
I’m using a regular (not subclassed) NSTableCellView in a view-based table view. It has the initial image and text field views. I added an NSStepper to the view.
The text field is bound to tableCellView.objectValue.quantity.
The stepper’s value is bound to tableCellView.objectValue.quantity too.
The problem is that when running the app, when I click the stepper it doesn’t seem to get the mouse event, neither arrow gets highlighted, the value is not incremented or decremented.
If I set the double action of the table view it gets triggered if I double-click the stepper as if it was transparent.
What am I missing?
Thanks!
You should look at the documentation but easiest is that you need to subclass NSTableView and override this method to validate the proposed first responder. As the document states NSTableViews disallow some controls to be used unless the row is first selected. Even then it still may discard some.
- (BOOL)validateProposedFirstResponder:(NSResponder *)responder forEvent:(NSEvent *)event {
return YES;
}
Further to the correct answer from Robert Payne, with Swift you could add an extension to NSTableView and not subclass it.
extension NSTableView {
override public func validateProposedFirstResponder(responder: NSResponder, forEvent event: NSEvent?) -> Bool {
return true
}
}
And I'd like to emphasis that it's the NSTableView not the NSTableViewCell.
I am trying to implement an Ipad application with gesture recognizer. In my application has some small UIView and each UIView has a sub view (UIButton). My need is,if click on a button ,the super view of this button's user interaction option will become YES and the Others views userinteraction option will become NO. After implementing this, the super view over rule the sub view (i.e. if the user-interaction option of one view become NO,this will affect the sub view).How can avoid the above issue?
Well, assuming you have a predefined number of views and subviews set-up in a storyboard or xib file you can add a property for each view. Then use the gesture recognizer to determine if the user taped a view. If they did you can use the properties you set up to set the appropriate views enabled property to YES or NO.
For example, add an IBAction to detect your gesture recognizer that does something similar to the following:
- (IBAction)tap:(UITapGestureRecognizer *)gesture
{
CGPoint tapLocation = [gesture locationInView:self.aViewWhereYouMonitorGestures];
for (UIView *view in self.aViewWhereYouMonitorGestures.subviews) {
if (CGRectContainsPoint(view.frame, tapLocation)) {
self.someView.enabled = YES; // or NO depending on what you want to do.
}
}
}
Suppose I have a Storyboard containing a view that contains a button. When the user presses this button, a popover comes up.
Thus, I need to set an anchor by dragging the segue to the button using Xcode (and then do performSegueWithIdentifier:).
So, my question is: is there a way to set this "anchor" programmatically?
Thank you.
In my case I've added programmatically several UIBarButtonItem.
The problem of only using an invisible view as an archor is that, if like in my case, the size of the UIBarButtonItem is changing it's size, the arrow of the popover doesnt appear centered, and althought it works, looks a bit strange.
How to solve it.
Create a small view in storyboard ( the size doesnt really matter ), make it invisible, and link it.
In my case this is called invisibleViewAsArchor
Connect the UIBarbutton item with the follow action.
-(IBAction) showMyPopover:(id)sender {
if([self.popoverController isPopoverVisible])
{
[self.popoverController dismissPopoverAnimated:YES];
}else{
self.invisibleViewAsArchor.frame = CGRectMake([sender view].frame.origin.x,
[sender view].frame.origin.y-50,
[sender view].frame.size.width,
[sender view].frame.size.height);
[self performSegueWithIdentifier:#"segue_to_something" sender:self];
}
}
as you can see before it shows the popover (with performSegueWithIdentifier), I'm changing the frame
of the Archor with the values from the button that has fired the event.
Hope it helps.
In the storyboard anchor the popover to some arbitrary button. Don't worry too much about which one as it will get overridden in the code.
In the view controller method prepareForSegue, add the code:
let dest = segue.destinationViewController
dest.popoverPresentationController?.barButtonItem = <your bar button here>
or if you want to anchor to a view instead
dest.popoverPresentationController?.barButtonItem = nil
dest.popoverPresentationController?.sourceView = <your view here>
You can't programmatically create segue's as explained here: Creating a segue programmatically, however, you can configure which destination controller you want to display at run-time. This is explained in the apple documentation here: Configuring the Destination Controller When a Segue is Triggered.
Hopefully this helps!
I had the same problem where I was creating a BarButtonItem programmatically. You may also be able to get around it by creating an invisible, disabled button which you can set as the anchor in IB.
It's easy enough to set up a table view to allow editing. Just add one line to your UITableViewController:
self.navigationItem.rightBarButtonItem = self.editButtonItem;
This line adds an edit button on the nav bar that will change the table to editing mode and change its button text to "Done" while editing.
Is it possible to set this up in Interface Builder? I see that you can add a UIBarButtonItem and can set its "Identifier" to "Edit", but I don't see the expected behavior.
BTW, what does the "Identifier" in the Attributes panel do?
Yes, you can add UIBarButtonItems in Interface Builder, and they should work.
The identifier lets you use a preset button (like Edit or Reload), or you can choose Custom and make your own button.
EDIT: I may be able to help further if you could explain how UIBarButtonItems added through IB don't work.
UPDATE: UIViewController.editButtonItem is a special method that returns a UIBarButtonItem that invokes the view's setEditing method. You can achieve the same effect by creating a method that does the same thing and connecting the selector to your UIBarButtonItem in IB.
In your header file:
- IBAction edit:(id)sender;
and in your implementation file:
- (IBAction) edit:(id)sender {
[self setEditing:YES animated:YES];
}
then connect the selector to the UIBarButtonItem.
However, you might not be able to create this connection in the default Navigation-Based Application template since the Table View is in a separate file.
Have a look here: http://blog.tmro.net/2009/05/uitabbarbuttonitem-did-not-change-its.html
If you want your button to be able to change its label dynamically make sure you use a custom identifier otherwise its title will be immutable.
We still can't seem to do this specifically in Interface Builder as of Xcode 9.4.1. It's very easy to do in code, though.
You don't need to set up the button in IB at all. Simply add this code in your viewDidLoad method:
navigationItem.leftBarButtonItem = editButtonItem
That automatically sets up the Edit button, which turns to Done so the user can end editing.
To do anything custom associated with the editing process, override the view controller's setEditing(_ editing: Bool, animated: Bool) method.
For example, if you have a table view whose editing needs to be turned on and off, you can do this:
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
tableView.setEditing(editing, animated: animated)
}
Make sure to call super.setEditing here.
Note: if you're using a UITableViewController, setEditing is already set up in the super class to handle the table view. You don't need to override it, unless you have other custom code you want to include when editing is enabled/disabled.