What's the best practice for setting zoom factor of an image within IKImageView via NSSlider?
I was able to bind a slider either to zoom in OR zoom out action of an IKImageView.
Obviously, what I'd rather see is a single slider controlling both those actions.
Best, if image is refreshed after each change of the slider (continuously, even if a mouse button is not released yet).
This demo explains a lot: ImageKitDemo
In particular, this snippet is what I was looking for:
- (IBAction) zoomSliderDidChange:(id)sender
{
[addProductPhotoImageView setZoomFactor:[sender floatValue]];
}
The Bindings way would be to bind both the Zoom Factor of the IK image view and the Value of the slider to the same property of your controller. When the slider changes the value of the property, the image view will be notified, and will go get the new value from your controller.
One advantage of this way is that you can add more ways of zooming in and out and the value in the slider won't go stale. For one example, if IKImageView adds pinch-zooming (or if it has it already—I don't have multi-touch on my Mac), the user can zoom that way and the slider will update automatically. That won't happen with the IBAction solution.
Another example would be Zoom In and Zoom Out menu commands (perhaps with ⌘+ and ⌘- keyboard shortcuts) that send action messages to your controller. Your controller would respond by increasing or decreasing the value of the property (using a setter method it implements). With Bindings, both the image view and the slider will update for free. Without Bindings, you would have to explicitly talk to both the image view and the slider, telling one to update its zoom factor and the other to update its slider.
A third example would be a “Zoom factor: X%” display in a corner of your window. With Bindings, this can update for free no matter how the user zooms the image: moving the slider thumb, pinching/unpinching the image, or pressing a menu item. Without Bindings, this would be yet another thing you have to talk to in your (at least three) change-the-zoom-value action methods.
Related
I have seen this in other programs and am trying to replicate it.
I have an image on one of my forms that someone can drag-and-drop an image into. I would like to allow the user to click on that image to pop up another dialog that they could instead select a "stock" image if they choose to.
I don't see an outlet I can use for the click and putting a transparent button over the top would defeat my ability to drag and drop an image on to it.
I realize I could just change the image to a button instead but I prefer to use an image if possible.
How can I make an image clickable?
This is OSX by the way, not IOS.
Quoting from another question:
By default, NSImageView doesn't react to -mouseDown:, or -mouseUp: like other NSControl subclasses (namely NSButton) do.
The solution is given in an answer elsewhere - subclass NSImageView and appropriately handle the click event (as linked).
Drag in the standard NSButton.
Uncheck the Bordered checkbox.
Clear the Title text.
Set the Image (and optionally, the alternate image).
Also, if you are using layout constraints to set button size to image view size, don't forget to set vertical hugging/compression resistance priorities to low values (say 1).
I must achievement somenthing tricky in my application for MAC OS, and because it's not easy to explain I will put an image: custom window
I created the NSWindow from image but the problema is how can create the NSView (the blue one) which is over and which have the purpose to block other action from user and just left small portion to be active. Any suggestion?
You can create a Custom NSView and draw clear color for enbaled rect area and disabled color for rest of the area. Capture the mouseDown event for the custom view and discard all the mouse events outside enabled rect area and if the mouse down in enabled area then call the mouse down event to the control behind the enabled area.
Wouldn't it be better to put up a sheet with a dialog to ask the user for the required information (and prevent interaction with the rest of the window) instead of mimicking a very un-Mac-like UI?
For example, consider the UI when creating a new project or adding a file to a project in Xcode.
If you really must attempt this, don't use a view to cover the window. Use another window. Make it borderless. Set its backgroundColor to [NSColor clearColor] and its opaque property to NO. Set its hasShadow property to NO. Set its frame to match the content rect of the window you want to block (or maybe its frame if you need to prevent interaction with its title bar).
Attach your overlay window to the main window as a child, using -addChildWindow:ordered:.
For the contentView of the overlay window, create a view that will draw the semi-transparent color everywhere except for over the control you want to leave accessible. To get that rect in the main window's coordinate system, you would use something like [specialView convertRect:specialView.bounds toView:nil].
Problem solved!:
Just check the "Unified Title And Toolbar" option of the NSWindow and the 1pixel-down problem goes away!
To change the toolbar height just select the Toolbar Item - Custom View and change size in the Size inspector.
==============================
If you know Xcode 5s layout than you should recognise this:
I want to build it for my own. So I dragged a Toolbar in the Window and added a NSPopUpButton. Then I changed the PopUp Button Cell Style to Radio and turned off the Arrows. So far so good.
The first thing I noticed is that the Toolbars has different heights. Does anybody know how to change this behaviour (without subclassing NSToolbar)?
The second and more annoying thing I noticed is that if I choose an Item from the PopUp Button the Image for the NSMenuItem move 1 pixel down.
EDIT: Xcode NSMenuItems don't move 1pixel down
Any suggestions about that thing?
NSToolbar, sadly, can’t really be subclassed. It’s a poorly-written class that tries to be very “magic,” so it’s not even a subclass of NSView—you can’t control how it draws at all, it creates a private view.
You can set its “sizeMode” but I assume you’ve already done that and found that the number of pixels high isn’t what you want.
The easiest thing to do is just leave space for your widgets at the top of your window (above the document content) and have autolayout position your buttons for you. (I haven’t been able to use a real NSToolbar in years because of its limitations.)
As for the popUp menu being mis-aligned with the button: where the menu draws is basically hard-coded, so if you use a button style that NSPopUpButton doesn't expect then the menu will be offset some.
If you’ve already tried just unchecking the “draws border” flag on a default-style NSPopUpButton (one fresh off the palette), There are two solutions for to try: One is to keep trying different buttonStyles that look correct to your eye until you find one that’s not offset. Two is to leave the buttonStyle do the default for NSPopUpButtons but subclass the buttonCell and have it not draw the border (but still leave room for it).
I have problem in playing with the UIScrollView i am using a customImage Object class to display images on scroll view and event fire on each image i achived it all but i have to do a extra work on it as the giving image showing that the middle image is pop out and fire event for that popout image...
i am confuse in it can anyone tell me how to achive this ....
please told me some steps to start with it..
You should be implementing the UIScrollViewDelegate protocol in the controller which should be handling the UIScrollView.
In there you will get a plethora of delegate callbacks such as when the scrollView moves or is decelerating towards a complete stop etc.
"UIScrollViewDelegate iOS reference"
You can implement any of the methods to suit your exact needs and modify the image's properties. To find which image is in the middle you would be comparing the contentOffset property of the scroll view o image locations.
My current iPad project-in-progress has the need for a sequence of events; It roughly reads like this:
→ User taps a button in a floating panel on top of a scroll view
→ floating panel animates to close
→ model reloads some data
→ scroll view displays new data
→ scroll view scrolls to a new content offset
→ new floating panel opens
This is not just a simple animation. Halfway through the sequence it needs to pause, the model needs to do some background processing and then report back when done, after which the sequence can be resumed. Also, the animation of the floating panels is achieved by using the convenient UIView animateWithDuration:animations:completion: method.
When I search stackoverflow and the rest of the web for sequencing solutions, the only thing that pops up is Core Animation. Yet this is not a case for CA.
What would be the best way to go about sequencing and timing method calls like this?
Cheers, EP.
CoreAnimation is a candidate, and is what is used internally by the UIView convenience class methods. As you say, it's not a complete solution, but is definitely worth keeping for the panel animations.
Otherwise, I'd imagine the overview would be:
User taps a button in a floating panel on top of a scroll view; view controller issues (i) a request for the animation on the floating panel; (ii) that the model begin to load data (I'll assume asynchronously)
At some point CoreAnimation reports that the animation is done. At some point the model reports that the new data has been loaded. The view controller waits until both things have occurred.
New data is pushed to the scroll view
The view controller scrolls the view, probably using either -scrollRectToVisible:animated: or -setContentOffset:animated: (I'll assume with animation set to 'YES')
the view controller also being the UIScrollViewDelegate, it waits to receive -scrollViewWillBeginDecelerating: or -scrollViewDidEndDecelerating:, or possibly checks the contentOffset in -scrollViewDidScroll:
at the right moment it then has CoreAnimation transition in the new floating panel.
So you're allowing the scroll view to handle its own animation and trusting it to report animation status, using CoreAnimation as your code already does for the panel and otherwise wiring everything together in the view controller. There's no need to use CoreAnimation explicitly, just stick with the UIView methods you're already using.
If your model is synchronous rather than asynchronous then just start the processing immediately after issuing the request to get rid of the first floating panel — CoreAnimation tasks continue even if the main thread is busy.