How to find the largest size of a view that does not make window larger than screen size? - swift

I'm working on a MacOS application that needs to display large images. if I naively set the ImageView to be the full size image, the application's window can be forced to become larger than the screen size. What I'd like to be able to do is work out how large I can make the image while keeping the entire window (which also contains other UI elements) on screen.
I know I can query the amount of available screen space using NSScreen:visibleFrame() but that does not seem to be much help since unless I make a whole load of assumptions about how much space the rest of the UI will take up which then defeats the point of having constraint based UI layout.
The other approach could be to find a way to constrain the window size and then let Cocoa work out the sizes of the views. However, it looks like the UI editors in Xcode only allows static sizes to be specified which is not much help.
It looks like this is possible in SwiftUI (https://www.hackingwithswift.com/quick-start/swiftui/how-to-adjust-the-way-an-image-is-fitted-to-its-space)
Image("example-image")
.resizable()
.aspectRatio(contentMode: .fit)
However, the application I'm working on needs to run on older versions of MacOS than supported by SwiftUI so I need to know how to do this in swift but using plain Cocoa.

The first thing I would try is to modify the priority of the constraints that make the image view large enough to accommodate the image. That would be its content compression resistance priority. I think if you set it to .dragThatCanResizeWindow then you might get the behavior you want for free. That's because the system already constrains a window to the screen size when you drag its edges. So, presumably, that implicit constraint has a higher priority than .dragThatCanResizeWindow.
If that doesn't do it, you can programmatically set a window's maximum frame size by setting its maxSize property. You'll want to set that each time the screen configuration changes or the window moves to a different screen. For the former, you can observe NSApplication.didChangeScreenParametersNotification. For the latter, your window delegate can implement windowDidChangeScreen(_:) or you can observe NSWindow.didChangeScreenNotification.

Related

How to resize an NSImageView in an NSStackView?

I'm working on a project where I want the following in an NSTableViewCell:
Image
Text
Subtitle text
The NSTableView is in a window which the user can expand or contract. When the window expands and contracts, the text wraps as needed.
That much is working.
When it comes to the image view, I can't get the thing to resize at all. I don't understand how the text automatically wraps, but images don't automatically scale. I've been working on iOS so long that I might have missed something in how stack views differ between iOS and macOS, but I never had this problem in iOS.
I don't have much code because the text wraps properly without any code at all, so instead I posted a minimal project showing the problem on Github:
NSImageTableViewTest
Some things I tried:
I have to set the width/height of the image view, or the text won't wrap. It seems to me that the reason why is that if I keep the image view unbound, the table view starts at the width of the image.
I tried setting the leading and bottom constraints of the image view to no avail.
I tried setting the constraints of the NSStackView, but that doesn't help constrain the frame of the image view.
Question: do I have to change the frame of the image view in code? I did try that, to no avail.
At this point, I'm stumped and I'm sure the fix is something easy that I overlooked.
Thanks.
The image view doesn't shrink because the default Content Compression Resistance Priority is too high. Set the Content Compression Resistance Priority to (a bit lower than) "Low (250)".

How to adjust apps UI to different screen size of iPhone models?

I find one solution is using extension to detect current iPhone model at runtime; however, it indeed involves massive of changes from my current code and design (i.e. change a lot of buttons location and size in single storyboard, a lot of constraints need to be updated as well etc). Are there any better solutions than this one? Thank you!
I always vote for creating constraints in IB as possible as you can , because it cuts time less than in code as you'll see the result instantly and do constraints fastly , the tip is to create it proportional as much as you can , look to the current device you do the constraints with as a generic device for example instead of setting a static height like 200 , look to design scale an make it proportional say 0.2 of screen height , same for width , you can make it also with origin constraints like top , leading but it needs some advanced constraints , make use of size classes and adaptive layout , also font adjustment , if all that fails hook the constraint and play with it in code

Scale Image to image view

I am currently building an iOS app. I'm still in the very beginner stage but know my way around programming.
However the Interface Builder gives me a headache.
I want to have an image view and then programatically load the image content (no problem here). However I want the image view never to change the initial size (now matter what the resolution of the image is).
Here is the trick though: The image view should be a certain distance from the left, right and top. On the bottom the imageview needs to keep a minimum distance but can be as large as possible (for different iPhones).
I am still lost what mode I need to set for the imageview, because currently every single setting resizes the view somehow.
Anybody got any advice on how to set the mode and the constraints?
You need to implement windowWillResize (or the live variant) from NSWindowDelegate and calculate the scale for the image in the view before re-displaying it.

Auto layout if orientation is not an issue?

I am currently trying to get the hang of Auto-layout in Xcode, and with it, i have found some problems.
Now, i don't have a 100% grasp on how auto-layout works exactly, so as i learn on it might become easy, but i think it is very hard to be honest. I am usually making games, and of thus, i programmatically add a lot of views to the screen. Now, auto-layout seems to mess everything up when i do this, so i constantly have to make sure that every single auto-layout feature is just right, and there are a bunch!
So, if you do not want to support other orientations, is auto-layout really needed? i mean, if i am making a game for the iPad and using landscape mode only, is there any reason for me to use auto-layout?
Thanks on advance
A couple of thoughts:
Auto layout is not mandatory.
But auto layout provides a mechanism for dealing with situations when views change sizes and/or locations:
changing orientation, as you pointed out;
supporting different screen sizes (e.g. iPhone 3.5" screen vs 4.0" screen);
controls whose size changes based upon content (e.g. a UILabel whose width expands to fit the text or whose lineCount is set to zero, meaning that its vertical will grow based the number of lines needed to fit all the text); with auto layout you can establish dependencies between controls so that, for example, as one control changes its own size/location, others can move/resize accordingly (e.g. to stay aligned with or make room for the other control); and
automatically update contentSize for UIScrollView objects.
Auto layout requires a little time to gain proficiency, but for dynamic, complex user interfaces, it can save you from having to write code to manually change layouts of views programmatically. But if you don't find yourself doing this sort of code, then you don't necessarily have to use auto layout.
I should acknowledge that there are some tasks that are trivial in a non-autolayout environment (e.g. animation of moving views), doing the same task in auto layout can be frustratingly complicated. But if you have complex interdependencies between views (either between the superview and its subviews or between sibling views), auto layout can be useful.
Autolayout simply provides rules for the views how they appear in all orientation.It is upto the user to define how to use it or you may follow the struct and spring model .
The major difference between the two is that there no dimensions involeve in the struct and springs while autolayout says the dimensions and values in whch views should be rearranged
An excellent beginner tutorial fo autolayout

iOS playing cards

I currently have an image which has every suit and value of a deck of playing cards in it. There is an UIImageView to show this picture, with width and height set to show just one card at a time and view mode set to "top left" so it doesn't stretch.
Now I'm just showing what happens to be the top left card, the ace of clubs. I tried finding a way to offset the view to show a different portion of the UIImage, but couldn't find a suitable property (tried fiddling with "frame" and "bounds").
Is there a way to get such an offset working, or am I going about this the wrong way? I'd like to keep all the cards in one image in "sprite sheet" style so that they would be easy to modify later instead of having a bunch of separate pics.
Set the bounds to what you'd like to show, enable 'clipToBounds' and make sure the content stretch mode is set properly. That should work.
EDIT: I do recommend making different images though, because of memory issues (even though not the whole image is shown, you still fully have it in memory).