Im trying to setup a multiline set of views in a UIScrollView and ultimately a UIStackView. I found out I need to dynamically set the scrollviews height to the content to make it work. So when I went to debug why the values never worked I found that the labelType.frame.size is giving me a massive width or like the text was never wrapped, and the height is the height of the devices view.
If I change around the anchors for the content view I can make the text never line break fueling what I see as the CGSize numbers corresponding to the visual size
While the parent view does not even get a size which is why the default UIScrollView won't even work
content frame (0.0, 0.0)
uitextType (6791.0, 478.0)
labelType (6781.0, 460.5)
In this example I am testing both UITextView and UILabel, I know UITextView is not recommended but testing anyway, it has the same behavior with or without
Worse case I guess I can mix SwiftUI into the Uiview and carry on with work.
override func viewDidLoad() {
super.viewDidLoad()
}
override func loadView() {
super.loadView()
let content = UIView()
content.backgroundColor = UIColor.green
content.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(content)
let constraints2 = [
content.topAnchor.constraint(equalTo: self.view.topAnchor),
content.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
content.heightAnchor.constraint(equalTo: self.view.heightAnchor, constant: 0),
content.widthAnchor.constraint(equalTo: self.view.widthAnchor),
// content.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
// content.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
]
NSLayoutConstraint.activate(constraints2)
let uitextType = UITextView()
uitextType.backgroundColor = .clear
uitextType.text = lotatext
uitextType.isScrollEnabled = false
uitextType.translatesAutoresizingMaskIntoConstraints = false
content.addSubview(uitextType)
uitextType.topAnchor.constraint(equalTo: content.topAnchor).isActive = true
uitextType.leadingAnchor.constraint(equalTo: content.leadingAnchor).isActive = true
uitextType.heightAnchor.constraint(equalTo: content.heightAnchor).isActive = true
uitextType.widthAnchor.constraint(equalTo: content.widthAnchor).isActive = true // -40 2x?! lame
uitextType.font = UIFont.preferredFont(forTextStyle: .body)
uitextType.contentInsetAdjustmentBehavior = .automatic
uitextType.sizeToFit()
uitextType.contentMode = .topLeft
let labelType = UILabel()
labelType.backgroundColor = .clear
labelType.text = lotatext
labelType.numberOfLines = 0
labelType.lineBreakMode = .byWordWrapping
labelType.translatesAutoresizingMaskIntoConstraints = false
content.addSubview(labelType)
labelType.topAnchor.constraint(equalTo: content.topAnchor).isActive = true
labelType.leadingAnchor.constraint(equalTo: content.leadingAnchor).isActive = true
labelType.heightAnchor.constraint(equalTo: content.heightAnchor).isActive = true
labelType.widthAnchor.constraint(equalTo: content.widthAnchor).isActive = true
labelType.font = UIFont.preferredFont(forTextStyle: .body)
labelType.sizeToFit()
print("content frame \(content.frame.size)")
print("uitextType \(uitextType.frame.size)")
print("labelType \(labelType.frame.size)")
}
// testing text
let lotatext = """
Every day is taco ipsum tuesday. It’s a wonderful morning for breakfast tacos. 50 cent tacos! I’ll take 30. CARNE ASADA!! BARBACOA!! I’d have to say, those tacos are on fleek. It’s long been rumored that the chupacabra is really just a crazed man who’s local taco shop went out of business. Does guac cost extra? BARBACOA!! TACOS!! It’s raining tacos, from out of the sky, tacos, don’t even ask why. CARNE ASADA!!
50 cent tacos! I’ll take 30. I’d have to say, those tacos are on fleek. Let’s do a beef and a chicken, and one with both. I’ve been following that taco truck around all day. Make it a double there pal. It’s long been rumored that the chupacabra is really just a crazed man who’s local taco shop went out of business. I think I’ve overdosed on tacos. Tacos Al pastor/De Adobada are made of thin pork steaks seasoned with adobo seasoning, then skewered and overlapped on one another on a vertical rotisserie cooked and flame-broiled as it spins.
... snipped extras paragraphs
"""
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
so i'm trying to implement a simple english to farsi dictionary in iOS
i'd like to include both words in one table cell, problem is that english is L>R and farsi is R>L, also i'd like to make the farsi word a bit bigger.
I created an AttributedMutableString and I thought I put down all the correct values but it looks like there is a problem since it isn't rendering correctly.
code:
cell.textLabel?.numberOfLines = 0
var myString = "\(englishConvo[indexPath.row])\n\(farsiConvo[indexPath.row])"
var mutableString = NSMutableAttributedString()
var lenOfLang1 = englishConvo[indexPath.row].characters.count
var lenOfLang2 = farsiConvo[indexPath.row].characters.count
let increaseFontSize = UIFont(name: (cell.textLabel?.font.fontName)!, size: (cell.textLabel?.font?.pointSize)! + 5)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = NSTextAlignment.Right
mutableString = NSMutableAttributedString(string: myString)
mutableString.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: NSRange(location: lenOfLang1 + 1, length: lenOfLang2))
mutableString.addAttribute(NSFontAttributeName, value: increaseFontSize!, range: NSRange(location: lenOfLang1 + 1, length: lenOfLang2))
cell.textLabel?.attributedText = mutableString
If i convert to a string using this code this is what I get
cell.textLabel?.text = String(mutableString)
Any thoughts / ideas would be super appreciated
Table cells already come with a layout that gives you two labels (text and detail), so why not just use it? Here, for example, in a language app of mine, I'm displaying a Latin word in the text label and an English translation in the detail label. You could easily do the same with Farsi and English.
I am making a game where there are clouds moving, and I want it so the clouds will fade away when the character lands on it. However, when I put the code, it fades away if the character goes around it and hits the bottom or the side of the cloud while it is still falling. Here is the code I have for detecting when the character and cloud have hit.
Is there anyway to determine when the character has landed on top of the cloud so it does not fade the cloud away if it hits it from the bottom or side while it is falling?
Here is code for declaring the objects:
Person.physicsBody?.usesPreciseCollisionDetection = true
Person.size = CGSizeMake(self.frame.size.width / 25, self.frame.size.height / 16.25)
Person.physicsBody = SKPhysicsBody(rectangleOfSize: Person.size)
Person.physicsBody?.restitution = 0
Person.physicsBody?.friction = 0
Person.physicsBody?.allowsRotation = false
Person.physicsBody?.affectedByGravity = true
Person.physicsBody?.dynamic = true
Person.physicsBody?.linearDamping = 0
Person.zPosition = 5
Person.physicsBody?.categoryBitMask = BodyType.PersonCategory.rawValue
Person.physicsBody?.contactTestBitMask = BodyType.CloudCategory.rawValue
Person.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame) * 1.7)
self.addChild(Person)
Cloud = SKSpriteNode(texture: NormalCloudTexture)
Cloud.zPosition = 7
Cloud.physicsBody?.usesPreciseCollisionDetection = true
Cloud.physicsBody?.affectedByGravity = false
Cloud.physicsBody?.allowsRotation = false
Cloud.size = CGSizeMake(self.frame.size.width / 8.05, self.frame.size.height / 40)
Cloud.physicsBody = SKPhysicsBody(rectangleOfSize: Cloud.size)
Cloud.physicsBody?.friction = 0
Cloud.physicsBody?.restitution = 0
Cloud.physicsBody?.dynamic = false
Cloud.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame) / 7.60)
addChild(Cloud)
Here is code for when the objects have hit:
func didBeginContact(contact: SKPhysicsContact)
{
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
switch(contactMask)
{
case BodyType.PersonCategory.rawValue | BodyType.CloudCategory.rawValue:
JumpContact = true
let CheckDelay = delay(0.055)
{
//cloud fades away here
}
I have not done it, but i have an idea. :)
I think you should do:
Track contact position with contactPoint property and then check if it is not touching x position of the cloud lower then few points from the top.
I hope it helps you. :)
Thank you for your recommendation! I decided to fool around, here is what you do guys!
//put like a few millisecond delay here, forgot it
if (Person.physicsBody?.velocity.dy == 0){//this means the person has stopped moving since it landed
//cloud fades away
}
I'm trying to use
NSBitmapImageRep.bitmapImageRepByConvertingToColorSpace(NSColorSpace.genericRGBColorSpace(), renderingIntent: NSColorRenderingIntent.Perceptual);
to convert an NSImage to a format that can be handled by openGL, and it works (unlike bitmapImageRepByRetaggingWithColorSpace()), but I get an error:
<Error>: The function ‘CGContextClear’ is obsolete and will be removed in an upcoming update. Unfortunately, this application, or a library it uses, is using this obsolete function, and is thereby contributing to an overall degradation of system performance.
which is sort of useless, because it's Apple's own code, and I can't seem to find an alternative to bitmapImageRepByConvertingToColorSpace(), or any note that it too is deprecated.
EDIT:
var image=NSImage(size: frame);
image.lockFocus();
//println("NSImage: \(image.representations)");
string.drawAtPoint(NSMakePoint(0.0,0.0), withAttributes: attribs);
var bitmap2=NSBitmapImageRep(focusedViewRect: NSMakeRect(0.0,0.0,frame.width,frame.height))?;
image.unlockFocus();
bitmap=bitmap2!.bitmapImageRepByConvertingToColorSpace(NSColorSpace.genericRGBColorSpace(), renderingIntent: NSColorRenderingIntent.Perceptual);
For some reason this question interested me. It looks like the solution is to lock focus on your NSImage, then use NSBitmapImageRep(focusedViewRect:) to create the NSBitmapImageRep.
I tried to recreate your situation (as I understand it) and then create an NSBitmapImageRep with the following code:
var img:NSImage = NSImage(size: NSMakeSize(200,200))
img.lockFocus()
let testString:NSString = "test String"
testString.drawAtPoint(NSMakePoint(10,10), withAttributes: nil)
img.unlockFocus()
println("img Description = \(img.description)")
I got the following description:
img Description = NSImage 0x608000067ac0 Size={200, 200} Reps=(
"NSCGImageSnapshotRep:0x61000007cf40 cgImage=CGImage 0x6100001a2bc0")
I then extended this code to:
var img:NSImage = NSImage(size: NSMakeSize(200,200))
img.lockFocus()
let testString:NSString = "test String"
testString.drawAtPoint(NSMakePoint(10,10), withAttributes: nil)
img.unlockFocus()
println("img Description = \(img.description)")
img.lockFocus()
var bitmapRep:NSBitmapImageRep = NSBitmapImageRep(focusedViewRect: NSMakeRect(0.0, 0.0, img.size.width, img.size.height))!
img.unlockFocus()
println("bitmap data planes = \(bitmapRep.bitmapData)")
println("bitmap pixels wide = \(bitmapRep.size.width)")
println("bitmap pixels high = \(bitmapRep.size.height)")
println("bits per sample = \(bitmapRep.bitsPerSample)")
println("samples per pixel = \(bitmapRep.samplesPerPixel)")
println("has alpha = \(bitmapRep.alpha)")
println("is planar = \(bitmapRep.planar)")
println("color space name = \(bitmapRep.colorSpace)")
println("bitmap format = \(bitmapRep.bitmapFormat)")
println("bytes per row = \(bitmapRep.bytesPerRow)")
println("bits per pixel = \(bitmapRep.bitsPerPixel)")
The output for the NSBitmapImageRep parameters was:
bitmap data planes = 0x000000010b6ff100
bitmap pixels wide = 200.0
bitmap pixels high = 200.0
bits per sample = 8
samples per pixel = 4
has alpha = true
is planar = false
color space name = Color LCD colorspace
bitmap format = C.NSBitmapFormat
bytes per row = 800
bits per pixel = 32
I've posted some new code below. I've created two NSBitMapImageRep just like your code (except that I used the method bitmapImageRepByRetaggingWithColorSpace), and I exported both of them to a PNG file. I got the same image in both PNG files.
But I'm wondering a couple of things. First, the difference in your two tests was not only the OS X version, but the hardware produced different color spaces. You should check to be sure bitmap2 is not nil.
Second, I'm wondering if OpenGL cares. If bitmap2 is not nil and you pass OpenGL bitmap2.bitmapData, does it work?
My new code (deleting most of the println):
var img:NSImage = NSImage(size: NSMakeSize(200,200))
img.lockFocus()
let testString:NSString = "test String"
let font:NSFont = NSFont(name: "AppleCasual", size: 18.0)!
let textStyle = NSMutableParagraphStyle.defaultParagraphStyle().mutableCopy() as NSMutableParagraphStyle
textStyle.alignment = NSTextAlignment.LeftTextAlignment
let textColor:NSColor = NSColor(calibratedRed: 1.0, green: 0.0, blue: 1.0, alpha: 1.0)
let attribs:NSDictionary = [NSFontAttributeName: font,
NSForegroundColorAttributeName: textColor,
NSParagraphStyleAttributeName: textStyle]
testString.drawAtPoint(NSMakePoint(0.0, 0.0), withAttributes: attribs)
img.unlockFocus()
println("img Description = \(img.description)")
img.lockFocus()
var bitmapRep:NSBitmapImageRep = NSBitmapImageRep(focusedViewRect: NSMakeRect(0.0, 0.0, img.size.width, img.size.height))!
img.unlockFocus()
let pngPath:String = "TestStringBeforeChange.png"
let imageProps = [NSImageCompressionFactor: NSNumber(float: 1.0)]
let outputImageData = bitmapRep.representationUsingType(NSBitmapImageFileType.NSPNGFileType, properties: imageProps)
let fileSavePanel = NSSavePanel()
fileSavePanel.nameFieldStringValue = pngPath
var savePanelReturn = fileSavePanel.runModal()
if savePanelReturn == NSFileHandlingPanelOKButton
{
var theFileURL = fileSavePanel.URL
var saveStatus = outputImageData?.writeToURL(theFileURL!, atomically: true)
}
let bitmapRep2 = bitmapRep.bitmapImageRepByRetaggingWithColorSpace(NSColorSpace.genericRGBColorSpace())
let pngPath2:String = "TestStringAfterChange.png"
let outputImageData2 = bitmapRep2!.representationUsingType(NSBitmapImageFileType.NSPNGFileType, properties: imageProps)
let fileSavePanel2 = NSSavePanel()
fileSavePanel2.nameFieldStringValue = pngPath2
var savePanel2Return = fileSavePanel2.runModal()
if savePanel2Return == NSFileHandlingPanelOKButton
{
var theFileURL2 = fileSavePanel2.URL
var saveStatus2 = outputImageData2?.writeToURL(theFileURL2!, atomically: true)
}
Sorry for all the posts, but I don't want to let this go, and it's interesting.
I created 3 PNG files: the first using the original NSBitmapImageRep, a second using an NSBitmapImageRep created with bitmapImageRepByRetaggingWithColorSpace and a third using an NSBitmapImageRep created with bitmapImageRepByConvertingToColorSpace (I, of course, got the system warning when I used this function).
Looking at these three PNG files in Preview's Inspector, they were all RGB color models; only the colorSynch profile for the first file was different from that of the second and third file. So I thought maybe there's no difference in the bitmapData among these files.
I then wrote some code to compare the bitmapData:
var firstRepPointer:UnsafeMutablePointer<UInt8> = bitmapRep.bitmapData
var secondRepPointer:UnsafeMutablePointer<UInt8> = bitmapRep2!.bitmapData
var firstByte:UInt8 = 0
var secondByte:UInt8 = 0
for var i:Int = 0; i < 200; i++
{
for var j:Int = 0; j < 200; j++
{
for var k:Int = 0; k < 4; k++
{
memcpy(&firstByte, firstRepPointer, 1)
firstRepPointer += 1
memcpy(&secondByte, secondRepPointer, 1)
secondRepPointer += 1
if firstByte != secondByte {println("firstByte = \(firstByte) secondByte = \(secondByte)")}
}
}
}
As I expected, there were no differences when I compared the bitmapData from the original bitmap rep to the bitmapData from the bitmap rep created with bitmapImageRepByRetaggingWithColorSpace.
It got more interesting, however when I compared the bitmapData from the original bitmap rep to the data from the bitmap rep created with bitmapImageRepByConvertingToColorSpace.
There were lots of differences in the data. Small differences, but lots of them.
Even though there were no differences I could see in the PNG files, the underlying data had been changed by bitmapImageRepByConvertingToColorSpace.
All that said, I think you should be able to pass .bitmapData from any of these bitmap reps to an OpenGL texture. The data from the bitmap rep created with bitmapImageRepByConvertingToColorSpace might create a texture that looks different, but it should be valid data.