4

Question

How can a UIView be created with a user-defined size and then scaled up/down to fit as a subview of a UIViewController?

Use-case

I am developing an application with a primary focus on showing a custom UIView on an external monitor attached to the iOS device. The custom view should be created to natively fit the external monitor. Let's say the external display has a resolution of 1920x1080. The UIView would be created to fit that size and then auto layout would do it's thing. - great!

Typically, the application user cannot actually see the external monitor, so another important part of the application is to provide a representation of the external monitor on the iOS device. Of course, these small window is not going to be the same resolution as the external display and simply creating another view and sticking it on the internal display is not going produce the same results because of AutoLayout.

Goal

I'd like to know how to create another custom view instance programmatically at the same dimensions as the external display (so the layout is identical) and then scale that view up/down to fill a subview on the internal display. Again, it is important that the preview window on the internal display is identical to what is being shown on the external display. I understand there may be some scaling artifacts - that is totally OK.

Application Example

The application in question can be viewed at liveevent.software. My question is in reference to the the external display and the preview of the external display as viewed on the iPad screen. Of course, we have this working already, but we are adding more features and need the local preview to be exactly the same as the external to the operator knows if a message is too long etc...

Important Notes

The UIView being scaled does not contain any gesture recognizers or other items requiring user interaction. Just a few UILabels.

The Issue

The current "working" solution is to create create two instances of the custom view and have them adapt according to auto-layout. While this produces a rough estimation of what is being displayed externally, it is not exact. For example, text may break a line on the iOS preview window but not on the actually external display (because it is larger dimensions).

Michael Voccola
  • 1,827
  • 6
  • 20
  • 46
  • 1
    Please, show us a *specific* issue, preferably with code. Not some "proof-of-concept" document discussing how an iOS app should look on an external monitor. Can it be done? Maybe. But you've shown no code! I actually decided to click on the link provided - how is your question different than "show me how to do this"? Of course, you have this working already.... then please, what's the issue? And yes, be SPECIFIC. –  Mar 20 '17 at 02:15
  • Are you able to get the size of the external monitor. If so I can give you a way to start calculating the size of everything to scale proportionally – agibson007 Mar 20 '17 at 02:21
  • @agibson007 Yes, the dimensions of the external monitor (window) are known and I'd like to use a default of 1280x720 if no external monitor is connected. – Michael Voccola Mar 20 '17 at 02:23
  • @dfd I have updated to explain the iissue in detail. Any code examples I show are going to be too far off course and definitely incorrect. They would distract from the question. – Michael Voccola Mar 31 '17 at 02:27

3 Answers3

2

Depending on how "real time" you need this to be, maybe you could take snapshots of the external UIView? This would result in an UIImage, which you can assign to an UIImageView on the internal display. The image dimensions can be set to whatever you want, and the UIImageView would take care of the scaling.

There are many good answers on how to take a snapshot of a view, for example : this one.

Community
  • 1
  • 1
Losiowaty
  • 7,911
  • 2
  • 32
  • 47
2

Instead of creating another instance of the view and using resources to update both accordingly to user actions I would create a snapshot of the view at any change, by using snapshotView method. In terms of performances the snapshotView is very efficient and returns a view object whose content is not editable. This means that you can scale it as you wish to have an exact mirror of your currentView on the second screen.

SnapshotView method probably uses gpu resources, leaving your CPU free to have an high frame rate and performances on your second screen.

Giuseppe Lanza
  • 3,519
  • 1
  • 18
  • 40
0

You could maybe create an exact duplicate UIView with same size, and then use CGAffineTransform to scale it to the new size (given that you know the dimensions it needs to fit)

CGAffineTransform is a GPU accelerated operation so performance should be rather optimal.

Only thing to note (as Documentation warns) is that it might not play nicely with Autolayout because frame property will be considered invalid. You will only have bounds and center to manipulate the view.

Noam
  • 620
  • 7
  • 13