I am currently playing with PlaygroundBook. From the Doc, it says that you can use LiveView.swift to present a always-on View in the liveView. So I create a SceneViewController in the Source Folder. In the SceneViewController, I create a Sphere which lightingModel is physicallyBased, and I using a 3D map as the background contents.
Then in the LiveView.swift
import PlaygroundSupport
let page = PlaygroundPage.current
page.current.liveView = SceneViewController()
But when I run it in the iPad Air Playground. I get no error, but the liveView didn't show anything!
I spend many years finding errors. And I have try to create a new iOS Project using the same SceneViewController, and it work very well. I got no idea.
In the last, I try to change the lightingModel to .phong, and change the background to the white color.
Then the magic thing happened! The liveView now show a black sphere and the white background.
Why?
From the WWDC Session, I learn that I can use proxy to communicate with main process in Contents.swift and LiveView process.
So next, I make a extension.
extension SceneViewController: PlaygroundLiveViewMessageHandler {
public func receive(_ message: PlaygroundValue) {
if case let .string(_) = message {
changeColor()
}
}
}
And inside the Contents.swift, I create a new function
func addSky() {
if let proxy = page.liveView as? PlaygroundRemoteLiveViewProxy {
proxy.send(.string("addSky"))
}
}
And everyTime I call it, The liveView changed, see the image below. It's the same as The first time I try to use a 3D map as the background.
Does anyone know what does it happened ?
Related
I am using a PDFView to display images in my app (built using SwifUI), simply for quick and easy pinch-to-zoom functionality. This worked perfectly in iOS 15, but since updating to iOS 16, the app freezes when attempting to load the image viewer (PhotoDetailView below). The issue persists across both the simulator and a physical device.
Here is the code I'm using:
import SwiftUI
import PDFKit
struct PhotoDetailView: UIViewRepresentable {
let image: UIImage
func makeUIView(context: Context) -> PDFView {
let view = PDFView()
view.document = PDFDocument()
guard let page = PDFPage(image: image) else { return view }
view.document?.insert(page, at: 0)
view.autoScales = true
return view
}
func updateUIView(_ uiView: PDFView, context: Context) {
// empty
}
}
When I run the code on iOS 16.0 in the simulator, I get 2 errors in the console:
[Assert] -[UIScrollView _clampedZoomScale:allowRubberbanding:]: Must be called with non-zero scale
[Unknown process name] CGAffineTransformInvert: singular matrix.
I have been able to isolate the issue to view.autoscales = true. If I print view.scaleFactor, I can see that it is 1.0 before the autoscale and 0.0 afterward (which is what appears to be prompting the errors). These errors also show up in the console when using iOS 15 in the simulator, but the images load as expected.
When view.autoscales = true is commented out, the image loads, albeit at a size that is much larger than the device screen.
Does anyone have any idea what may be causing this? I'd really like to avoid having to build a custom viewer, since I'm just trying to let users quickly pinch to zoom on images.
I managed to resolve this issue. I'm posting my solution here, in case anyone else runs into the same type of problem.
The issue only occurred when using a NavigationLink to navigate to PhotoDetailView. This led me to look more closely at my navigation stack.
After some digging, I found that the problem was related to my use of .navigationViewStyle(.stack) on the NavigationView. I needed this modifier to get things to display correctly on iOS 15, but the same modifier was breaking my image viewer with iOS 16.
My solution was to create a custom container to replace NavigationView, which conditionally uses NavigationStack for iOS 16, or NavigationView + .navigationViewStyle(.stack) for iOS 15. That worked like a charm and my image viewer is back in action.
I found inspiration for my custom container here: https://developer.apple.com/forums/thread/710377
I have a problem in my iPhone app when trying to instantiate an ARSCNView again, after destroying it.
In my ViewController I programmatically create an ARSCNView for motion capture interaction:
func addARSceneView() {
arSceneView = ARSCNView(frame: self.view.frame)
arSceneView.loops = true
arSceneView.session.delegate = self
self.view.addSubview(arSceneView)
arSceneView.session.run(ARBodyTrackingConfiguration())
}
When the user leaves this part of the app, I tear it down like this:
func removeARSceneView() {
arSceneView.session.pause()
arSceneView.pause(self)
arSceneView.session.delegate = nil
arSceneView.removeFromSuperview()
arSceneView = nil
}
Later, when I try to instantiate an ARSCNView for the second time using the first function above, it crashes with an EXC_BAD_ACCESS in the constructor:
I also tried to use a view from a xib which contains an ARSCNView but the same problem occurs, in that case in the init(coder) function of that view.
I found nothing on this problem, I guess usually developers only create an ARSCNView once.
TLDR: Turn "Metal API Validation" on in your scheme.
I found the culprit, after creating a sample project with only the ARSCNView, which did not have this problem. I started by stripping everything away from my original project until it was as barebones as the sample. That did not solve it, so I compared every little setting of the two, and behold: in the "Run" scheme of the original project, under "Diagnostics", I had "Metal – API Validation" ticked off. I don't remember when and why I did that; I assume it was some attempt to improve performance at one point. However, enabling this checkbox solved the problem completely.
I was requested to show two Splash Screens when app launch. one
for a specific group of customers and other for another group of
customers. As I know, Apple doesn't allow to show two splash
screens, because it is already signed to Bundle. so I decided to
use an UIImageView and change the image by checking the group.
To check the group I used deep links which provide by the Branch.io. when someone came from the referral link which we created, it show one image and if someone came from normal way we show another image as launch image, instead of splash screen. it works properly.
But when the first launch it shows Black Screen for five to six seconds(considerable time) and show the image.
If it is not the first time, it works properly.(black screen for 1 to 2 second.)
Below is the way which I used to check the condition and show the image in another viewController.
in AppDelegate, inside the didFinishLaunchWithOption method I checked with branch like below.
let branch : Branch = Branch.getInstance()
// branch.setDebug()
branch.initSessionWithLaunchOptions(launchOptions) { (params, error) in
if error == nil {
let clickedBranchlink : Bool = params["+clicked_branch_link"] as! Bool
let isfirstSession : Bool = params["+is_first_session"] as! Bool
if clickedBranchlink == true {
let theReferrer : String = params["referrer"] as! String
if theReferrer == "groupA" {
// in here I checked the group and set userdefault values and navigate to the view which the image view has and show the image according to this condition.
}
}
}
NOTE: is there a way to increase the process of this and reduce the
black screen. do I do this inside a main thread. because first time it
avoid to go through the branch.initSessionWithLaunchOptions and then
it goes through it. hope your help with this.
This initSessionWithLaunchOptions will be called every time you launch the app and the app is not in the background. Given your observation that the issue only occurs the first time the app is installed, my hunch is that you have code running in didFinishLaunchingWithOptions before the Branch initSessionWithLaunchOptions function is called.
The Branch initialization process involves sending a network request and then waiting for a response, so this is always going to take some time - but there will be no difference in the time it takes on install vs. any other open. Start this asynchronous Branch initialization as quickly as possible, before any other code in didFinishLaunchtingWithOptions executes, and you should be able to reduce the time before the splash page displays. This should eliminate any variability in the time it takes to display the splash image that you believe may be related to Branch.
I have a Today Widget for my app, however I have been told about an issue with it.
Basically, what seems to be happening (I can't test this for myself) is that the widget will sometimes just display 'unable to load' and other times it will just display with a height of 0.
I can't really see why this is happening. I've tested it out on my device and the simulator for weeks now and have never ran into this issue.
I was wondering if it could possibly be down to the refresh code:
func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)!) {
// Perform any setup necessary in order to update the view.
var defaults = NSUserDefaults(suiteName: "group.AffordIt")
var newCheck = defaults.boolForKey("new")
if newCheck == true {
completionHandler(NCUpdateResult.NewData)
} else {
completionHandler(NCUpdateResult.NoData)
}
}
'newCheck' is true whenever something changes within my app that needs to be displayed in the widget.
Does anyone know what the possible causes of these issues are?
"unable to load" message appears if your extension crashes often. You can try to re-enable it by removing and adding the extension again.
Are you using your own view controller and xib instead of using storyboard? If yes, it is probably that you didn't set the preferredContentSize in your view controller.
try to put the following code in the init function of ur view controller:
self.preferredContentSize = CGSizeMake(320, 100);
I have just began the extension programming today so I am not sure is it really helpful for u or not. Here is the result in my own widget:
Press Edit button in today extensions
Remove your extension
Add your extension again.
I'm trying to have a loading screen that pops up as soon as you run that executable that launches the game, whilst the game loads I want to display an image on the desktop much like how Gamemaker allows you to have a loading image.
I've had a brief look around and most people want an image to be shown whilst they load content which is not what I want, or perhaps it is... =P
My guess would be to set the game window borderless at the start, load the splash screen, draw it, then begin all the main loading (Specifically loading DirectInput through SlimDX takes a while). However would this support having a transparent/irregular shaped image? E.G if I wanted a borderless circle to be displayed whilst the game loads, would that be possible?
Thanks.
It's very simple. Just implement System.Threading and you're done.
Here's how it works, first add:
using System.Threading;
to the top of your class, then add the following things:
//the enum for state types
enum GameState
{
Loading,
StartMenu
}
//Init our gameState enum as variable
GameState gameState;
protected override void LoadContent()
{
gameState = GameState.Loading;
spriteBatch = new SpriteBatch(GraphicsDevice);
device = GraphicsDevice;
Window.Title = "Your Window";
//Other stuff that you had here before, now go in LoadGame()
loadingscreen = Content.Load<Texture2D>("loading");
Thread bgLoad = new Thread(new ThreadStart(LoadGame));
bgLoad.IsBackground = true;
bgLoad.Start();
}
public void LoadGame()
{
//Loading stuff here
gameState = GameState.StartMenu; //or GameState.Playing
}
and then put a loading texture in your Content Project
If I understand you correctly, you essentially want to have a window opened that is not full screen that also lacks the regular border and buttons that accompanies a window.
I can't test this but this should be a good start.
Here!
I would start by creating a bare bones Game1 class that can track an image and keep track of time for a timer.
Later you could add logic that actually tracks the loading of assets in the main program.
To start I'd just test it for a fixed time like 3 seconds.