I am developing an App with Coremotion and Swift and only for landscape mode. I have the accelerometer (part of Coremotion) working. But when my iPhone orientation is Portrait, the accelerometer is active at the moment.
When I start the app in portrait mode, then it is not possible to stop the accelerometer. Because the app is designed for only landscape and then there is no possibility to test on portrait mode (Swift things de iPhone is always in landscape mode).
Can someone tell me how to make accelerometer only active by starting the app, when the iPhone is only in landscape mode?
Here some code:
viewdDidLoad:
if(motionManager.isDeviceMotionAvailable){
motionManager.startDeviceMotionUpdates();
motionManager.deviceMotionUpdateInterval = 1.0/60.0;
}
motionManager.startAccelerometerUpdates()
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval):
if let rot = motionManager.deviceMotion?.attitude{
cameraNode.eulerAngles = SCNVector3Make(Float(rot.roll +
M_PI/2), -Float(rot.yaw), -Float(rot.pitch))
Edit: Making sure this has been done. See below image.
Try :
viewDidAppear() {
super.viewDidAppear()
if UIDevice.current.orientation == UIDeviceOrientation.landscapeLeft || UIDevice.current.orientation == UIDeviceOrientation.landscapeRight {
if(motionManager.isDeviceMotionAvailable){
motionManager.startDeviceMotionUpdates();
motionManager.deviceMotionUpdateInterval = 1.0/60.0;
}
motionManager.startAccelerometerUpdates()
} // else you could do a notification on orientation left/right
}
Related
In My case i am changing my layouts of the view depending on the traitCollection.horizontalSizeClass
Here is my Code snippet .
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if traitCollection.horizontalSizeClass == .regular {
// 2
NSLayoutConstraint.deactivate(compactConstraints)
NSLayoutConstraint.activate(regularConstraints)
// 3
socialMediaView.axis = .horizontal
} else {
// 4
NSLayoutConstraint.deactivate(regularConstraints)
NSLayoutConstraint.activate(compactConstraints)
socialMediaView.axis = .vertical
}
}
Every things working as directed in iphone 7 plus and iphone x in portrait-mode
and in landscape mode i want the rabbit image comes to left side and the stackview of all socialMedias axis will be horizontal
but in iphone X landscape mode its not coming while in phone 7 its coming .Check the below screen shots
Looking at your question and condition, I found a problem in your condition. you should check for the verticalSizeClass instead of horizontalSizeClass.
WHEN CHECK FOR HORIZONTAL SIZE CLASS.
IN PORTRAIT: All iPhone Devices has compact width, so every time, it will go to else condition and set the view properly.
IN LANDSCAPE: All iPhone Plus (iPhone 6s Plus, iPhone 7 Plus and iPhone 8 plus) Devices has Regular width and All other iPhone (iPhone 6s, 6SE, iPhone 7 and iPhone 8, iPhone X) Devices has Compact width, so for all plus devices it will works fine but not for others.
FOR PORTRAIT:
FOR LANDSCAPE:
For more, read official doc here
So, update your code to this.
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if traitCollection.verticalSizeClass == .regular {
NSLayoutConstraint.deactivate(compactConstraints)
NSLayoutConstraint.activate(regularConstraints)
socialMediaView.axis = .horizontal
} else {
NSLayoutConstraint.deactivate(regularConstraints)
NSLayoutConstraint.activate(compactConstraints)
socialMediaView.axis = .vertical
}
}
Try and share the results.
I am trying to build a simple swift (4) macOS app to use an iPhone camera connected to my Mac.
I have started an blank macOS template app and have turned on sandbox to allow camera, mic and USB and added the following code to my ViewController.
import Cocoa
import AVFoundation
class ViewController: NSViewController {
#IBOutlet weak var camera: NSView!
override func viewDidLoad() {
super.viewDidLoad()
camera.layer = CALayer()
let session:AVCaptureSession = AVCaptureSession()
session.sessionPreset = AVCaptureSession.Preset.high
let device:AVCaptureDevice = (AVCaptureDevice.default(for: AVMediaType.video))!
// let listdevices = (AVCaptureDevice.devices())
do {
try session.addInput(AVCaptureDeviceInput(device: device))
//Preview
let previewLayer:AVCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: session)
let myView:NSView = self.view
previewLayer.frame = myView.bounds
previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
self.camera.layer?.addSublayer(previewLayer)
session.startRunning()
// print(listdevices)
// print(device)
} catch {
print(device)
}
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}
In storyboard I have dropped in a Custom View.
App builds ok and uses facetime camera no problem, however with iPhone connected I dont see if as a device that AVFoundation can use. Not sure on next steps on how to get the previewLayer to select the USB camera to use aka iPhone.
p.s Needs to be landscape for all cameras orietation
According to this Apple Developer Forum post, capturing the camera of a connected iOS device from a macOS app is not supported.
The closest you can do (as the post suggests), is to capture the screen of the iOS device while the camera (Camera.app) is running, effectively capturing the live camera preview (or you can roll your own companion camera app in iOS, if you want to remove the camera app’s UI from the captured screen).
As there is no autofocus in ARKit, I wanted to load ARKit in a view that is half the screen and second half will have AVFoundation -> AVCamera.
Is it possible to load AVCamera and ARKit simultaneously in same app?
Thanks.
Nope.
ARKit uses AVCapture internally (as explained in the WWDC talk introducing ARKit). Only one AVCaptureSession can be running at a time, so if you run your own capture session it’ll suspend ARKit’s session (and break tracking).
Update: However, in iOS 11.3 (aka "ARKit 1.5"), ARKit enables autofocus by default, and you can choose to disable it with the isAutoFocusEnabled option.
Changing the camera focus would disrupt the tracking - so this is definitely not possible (right now at least).
Update: See #rickster answer above.
I managed to use AVFoundation with ARKit by calling self.sceneView.session.run(self.sceneView.session.configuration!) right after taking the photo.
Use self.captureSession?.stopRunning() right after taking photo to make the session resume faster.
self.takePhoto()
self.sceneView.session.run(self.sceneView.session.configuration!)
func startCamera() {
captureSession = AVCaptureSession()
captureSession.sessionPreset = AVCaptureSession.Preset.photo
cameraOutput = AVCapturePhotoOutput()
if let device = AVCaptureDevice.default(for: .video),
let input = try? AVCaptureDeviceInput(device: device) {
if (captureSession.canAddInput(input)) {
captureSession.addInput(input)
if (captureSession.canAddOutput(cameraOutput)) {
captureSession.addOutput(cameraOutput)
captureSession.startRunning()
}
} else {
print("issue here : captureSesssion.canAddInput")
}
} else {
print("some problem here")
}
}
func takePhoto() {
startCamera()
let settings = AVCapturePhotoSettings()
cameraOutput.capturePhoto(with: settings, delegate: self)
self.captureSession?.stopRunning()
}
I am having deep trouble understanding how the resolution on different devices work. so what I have done is made a background image 1024 x 768 then tested on an iphone 5 device. when i run it, the bottom half of the screen is chopped off so as the top. I did use AspectFill as my scale mode, but even when i test it on iphone 6 or 6+, the background is still chopped off.
the following is my code for gameviewcontroller
import UIKit
import SpriteKit
class GameViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let scene = GameScene(size: CGSize(width: 1024, height: 768))
let skView = self.view as! SKView
skView.multipleTouchEnabled = true
if GameSettings.Debugging.ALL_TellMeStatus {
skView.showsFPS = GameSettings.Debugging.ALL_ShowFrameRate
skView.showsNodeCount = GameSettings.Debugging.ALL_ShowNodeCount
skView.showsDrawCount = GameSettings.Debugging.IOS_ShowDrawCount
skView.showsQuadCount = GameSettings.Debugging.IOS_ShowQuadCount
skView.showsPhysics = GameSettings.Debugging.IOS_ShowPhysics
skView.showsFields = GameSettings.Debugging.IOS_ShowFields
}
skView.ignoresSiblingOrder = true
scene.scaleMode = .AspectFill
_ = SGResolution(screenSize: view.bounds.size, canvasSize: scene.size)
skView.presentScene(scene)
}
override func shouldAutorotate() -> Bool {
return true
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return .Landscape
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Release any cached data, images, etc that aren't in use.
}
override func prefersStatusBarHidden() -> Bool {
return true
}
}
and my code for adding the background image in.
let background = SKSpriteNode(imageNamed: "Artboard 1")
background.posByCanvas(0.5, y: 0.5)
background.xScale = 1.2
background.yScale = 1.2
background.size = self.frame.size
background.zPosition = -1
addChild(background)
is this the right way to start the screen size or should i start with an iPad screen size then descale it? If anyone can lead me on how to attack this problem that would be great!!
Aspect fill is going to chop off parts of your background.
Your scene has an aspect ratio of 4:3
Your device has an aspect ratio of 16:9
AspectFill will scale your scene in its current aspect ratio(4:3) till the farthest borders are filled, allowing for the entire view to show the scene and have no black borders;
AspectFit will scale till the nearest borders are filled in, which will give you black bars to preserve the aspect ratio.
If you want the 4:3 to not be preserved, then you use .Fill, this of course is going to make your sprites fatter on 16:9 because it will just stretch the scene till it hits all 4 borders
Finally you have .ResizeFill, and what this does is resizes the scene bounds to match your screen size, so if you start with a 1024x768 scene, it will turn it into a 736x414 scene when you view it on iPhone 6+ (This is because we are working in points, not pixels, the pixel count would be x3 (so 2208x1242) which hardware will shrink to 1920x1080).
You need to take a step back and evaluate how you want your game to look on 3 different aspect ratios
16:9,3:2, and 4:3, and determine which of the 4 methods above works best for you.
Now in my opinion, I find that Aspect Fill works best, and I just plan for the 16:9 aspect ratio, making sure I do not put any important information in the areas that may be cropped for a game, but this does not work for everybody, and unfortunately nobody can help you with this part, since it is your game and you are the one that determines its look and feel.
I have 4 scenes in my game
I need to set scene 1 and scene 3 in landscape mode, scene 2 and scene 4 in portrait mode
how can I do this?
please help me out...
I'm searching for a long time but couldn't find out the answer
You can have a script that checks for the actual level and changes the orientation in according to the retrieved value.
As an example:
function Start(){
if (Application.LoadedLevel == 1)
Screen.orientation = ScreenOrientation.LandscapeLeft;
else if (Application.LoadedLevel == 2)
Screen.orientation = ScreenOrientation.Portrait;
//...
}
More info about usage and orientation values.
Since around Unity 5.3 there is a new API for getting the current scene.
This example forces the screen orientation on mobile devices to portrait on a scene called "GameView" and landscape otherwise.
using UnityEngine;
using UnityEngine.SceneManagement;
public class ScreenOrientationScript : MonoBehaviour {
void Start () {
if (Application.isMobilePlatform == true) {
if (SceneManager.GetActiveScene().name == "GameView") {
Screen.orientation = ScreenOrientation.Portrait;
} else {
Screen.orientation = ScreenOrientation.Landscape;
}
}
}
}
Sample iOS setting to allow orientations
Unity uses single/sole activity for ALL Levels/Scenes, which is com.unity3d.player.UnityPlayerActivity, as can be found in AndroidManifest.xml file.
So all you need do is to specify the orientation in the Player Setting Inspector (Default Orientation part):