How do you set previewLayer.connection.videoOrientation in Swift 2? - swift2

In Objective-C you can do this:
if ( UIDeviceOrientationIsPortrait( deviceOrientation ) || UIDeviceOrientationIsLandscape( deviceOrientation ) ) {
AVCaptureVideoPreviewLayer *previewLayer = (AVCaptureVideoPreviewLayer *)self.previewView.layer;
previewLayer.connection.videoOrientation = (AVCaptureVideoOrientation)deviceOrientation;
}
But in Swift, what's the best way to translate this last line? You can't do "deviceOrientation as AVCaptureVideoOrientation".
Best I could come up with so far is:
if(UIDeviceOrientationIsPortrait(deviceOrientation) || UIDeviceOrientationIsLandscape(deviceOrientation)) {
let myPreviewLayer: AVCaptureVideoPreviewLayer = self.previewLayer
myPreviewLayer.connection.videoOrientation = AVCaptureVideoOrientation.init(rawValue: deviceOrientation.rawValue-1)!
}
But this seems inelegant. The -1 is there because it's just an enum at the end of the day, and the UIDeviceOrientation enum has an "Unknown" one at position 0 that the AVCaptureVideoOrientation does not have...

This does a great job on swift 4:
previewLayer.connection?.videoOrientation = AVCaptureVideoOrientation(rawValue: UIApplication.shared.statusBarOrientation.rawValue)!

try this
let avLayer = (self.previewView.layer as AVCaptureVideoPreviewLayer)
let connection = avLayer.connection
let orientation = AVCaptureVideoOrientation(rawValue: self.interfaceOrientation.rawValue)!
connection.videoOrientation = orientation

This is the conversion I got:
if UIDeviceOrientationIsPortrait(deviceOrientation) || UIDeviceOrientationIsLandscape(deviceOrientation) {
var previewLayer: AVCaptureVideoPreviewLayer = previewView.layer
previewLayer.connection.videoOrientation = deviceOrientation
}
The converter I used tends to not know what the code is supposed to look like some times (Int vs. CGFloat) so it might not work without de-bugging. let me know if it does what you want, for example, the variable could probably be changed to a constant.

connection.videoOrientation = AVCaptureVideoOrientation.Portrait
You can find the constants AVCaptureVideoOrientation values in swift header files. (Swift 2)

Related

Heartrate with no decimal places

Im doing a watch app for the Apple Watch in Xcode and the sample code from the Apple Developer site SpeedySloth: Creating a Workout has the HeartRate rounded to one decimal place, e.g. 61.0
How can I fix this?
case HKQuantityType.quantityType(forIdentifier: .heartRate):
/// - Tag: SetLabel
let heartRateUnit = HKUnit.count().unitDivided(by: HKUnit.minute())
let value = statistics.mostRecentQuantity()?.doubleValue(for: heartRateUnit)
let roundedValue = Double( round( 1 * value! ) / 1 )
label.setText("\(roundedValue) BPM")
I tried changing both the 1's in there to 0 but that gave me a 6.1 BPM or a 0.0 BPM
Thanks
A simple solution is to round to an integer and show the integer.
let value = // ... some Double ...
let s = String(Int(value.rounded(.toNearestOrAwayFromZero)))
label.setText(s + " BPM")
Properly, however, you should put formatting a string based on a number into the hands of a NumberFormatter. That's its job: to format a number.
let i = value.rounded(.toNearestOrAwayFromZero)
let nf = NumberFormatter()
nf.numberStyle = .none
let s = nf.string(from: i as NSNumber)!
// ... and now show the string

line spacing in dynamically created swift 3/xcode labels

I'm having an issue where I am getting a list of skills back from an api and I want them to stack one on top of the other in two different sections, a left column and a right column. It works well but if the skill is longer than the width of the label it drops to a new line with the same spacing as the rest of the labels. The skill Adobe Creative Suite looks like Adobe Creative as one and Suite as another. I would like Suite to be underneath Adobe Creative but much closer so you can tell it's all one skill.
My code is here:
lblLeft.text = ""
lblRight.text = ""
if let expertiseCount = helper.expertise {
for i in 0..<expertiseCount.count {
if i % 2 == 0 {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 10
let attrString = NSMutableAttributedString(string: lblLeft.text! + "\(expertiseCount[i].name ?? "")\n")
attrString.addAttribute(NSParagraphStyleAttributeName, value:paragraphStyle, range: NSMakeRange(0, attrString.length))
lblLeft.attributedText = attrString
} else {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 10
let attrString = NSMutableAttributedString(string: lblRight.text! + "\(expertiseCount[i].name ?? "")\n")
attrString.addAttribute(NSParagraphStyleAttributeName, value:paragraphStyle, range: NSMakeRange(0, attrString.length))
lblRight.attributedText = attrString
}
}
}
I've already tried line spacing and that just changes the size between all lines so the space between Adobe Creative and Suite takes on that change as well.
Try:
lblLeft.numberOfLines = 0
lblLeft.lineBreakMode = .byWordWrapping
lblLeft.sizeToFit()
By setting number of lines to zero and turning word wrapping on, the label will grow to the required number of lines. sizeToFit() should size it properly.

Can DateComponentsFormatter format fractional seconds?

I want to print, e.g., the value 1.5 as "1.5 sec", like Safari's timeline does, and I'm trying to use DateComponentsFormatter for it.
Unfortunately, its .allowedUnits only goes down to .second (even though the enum has .nanosecond). I tried setting .allowsFractionalUnits = true, but I'm still getting "0 sec".
Is there any way to get fractional seconds out of DateComponentsFormatter?
For positional units style, DateComponentsFormatter can be used together with NumberFormatter to get locale-aware string.
func format(_ seconds: TimeInterval) -> String {
let components = DateComponentsFormatter()
components.allowedUnits = [.minute, .second]
components.allowsFractionalUnits = true // does not work as expected
components.unitsStyle = .positional
components.zeroFormattingBehavior = .pad
let fraction = NumberFormatter()
fraction.maximumIntegerDigits = 0
fraction.minimumFractionDigits = 0
fraction.maximumFractionDigits = 3
fraction.alwaysShowsDecimalSeparator = false
let fractionalPart = NSNumber(value: seconds.truncatingRemainder(dividingBy: 1))
return components.string(from: seconds)! + fraction.string(from: fractionalPart)!
}
print(Locale.current) // ru_RU (current)
print(format(600.5)) // 10:00,5 <- note locale specific decimal separator
Unfortunately, using this method for other date styles is even more hacky.

Swift 3 Local Notifications - Setting Automatic Timezone

So this worked flawlessly in Swift 2 but in Swift 3 it has problems:
func myNotifications () {
let interval = 2.0
var daysOut = 2.0
let myArray =getArray()
for i in 0..<myArray.count {
let message = ("\(myArray[i])\n-\(myArray[i])")
let localNotification = UILocalNotification()
localNotification.fireDate = Date(timeIntervalSinceNow: (60*60*24*daysOut))
localNotification.alertBody = message
localNotification.timeZone = NSTimeZone.autoupdatingCurrent
localNotification.category = "Message"
UIApplication.shared.scheduleLocalNotification(localNotification)
daysOut += interval
}
let arrayCount = Double(myArray.count)
let lastNotif_Date = Date(timeIntervalSinceNow: (60*60*24*interval*(quoteCount+1)))
userPref_NSDefault.set(lastNotif_Date, forKey: "notification_EndDate")
}
Specifically, this line no longer works which is a big deal because I have users in multiple timezones and I want to make sure this works:
localNotification.timeZone = NSTimeZone.autoupdatingCurrent
I get the error message:
Type "NSTimeZone" has no member "autoUpdatingCurrent"
Any ideas? I tried "timeZone.automatic", ".automatic", and some other variations but haven't been able to figure it out.
autoupdatingCurrent != autoupdatingCurrent
NSTimeZone has been renamed to TimeZone

Easeljs keep object within bounds

I am working on a drawing application in HTML5 canvas, using Easeljs. So far I am able to drag and drop objects into the field, but I only want them within certain bounds.
To illustrate:
Objects 1, 2, 4 and 5 should get deleted, but object 3 should be kept.
I have tried using hitTest(), but that didn't work properly (I probably did something wrong). I would love to post the code I used, but my PC froze while working on it... Thought I'd better ask while unfreezing, haha.
Here is a quick drag and drop sample with bounds constraining:
http://jsfiddle.net/xrqatyLs/8/
The secret sauce is just in constraining the drag position to your own values.
clip.x = Math.max(bounds.x, Math.min(bounds.x + bounds.width - clipWidth, evt.stageX));
clip.y = Math.max(bounds.y, Math.min(bounds.y + bounds.height-clipHeight, evt.stageY));
Here is another more complex example that manually checks if one rectangle intersects another rectangle:
http://jsfiddle.net/lannymcnie/yvfLwdzn/
Hope that helps!
Solution:
var obj1 = obj.getBounds().clone(); // obj = a pylon
var e = obj1.getTransformedBounds();
var obj2 = bg.getBounds().clone(); // bg = the big green field
var f = obj2.getTransformedBounds();
if(e.x < f.x || e.x + e.width > f.x + f.width) return false;
if(e.y < f.y || e.y + e.height > f.y + f.height) return false;
return true;
After all it's so simple, but I guess I was working on it for so long that I started to think too hard...

Resources