how to Horizontal box UIButtons? - xcode

I am required to make a view where number of buttons to be displayed will depend upon the argument to init. how can i make it possible horizontal box UIButtons?
override func viewDidLoad() {
var bs = 0;
for index in 1...20
{
bs+=50;var x = CGFloat(bs)
let button = UIButton(type: UIButtonType.System) as UIButton
button.contentMode = UIViewContentMode.ScaleToFill
button.frame = CGRectMake(x, 50, 40, 40) // X, Y, width, height
button.backgroundColor = UIColor.whiteColor()
button.setTitle("12", forState: UIControlState.Normal)
button.addTarget(self, action: "buttonAction:", forControlEvents: UIControlEvents.TouchUpInside)
view.addSubview(button);
}
}
i want to like this

You should probably look at UICollectionView
If you don't want to use a UICollectionView, I put up for you this small sample, on which you can try to build on, whether using a UIView or UIScrollView:
let view = UIView(frame: CGRect(origin: CGPointZero, size: CGSize(width: 300, height: 300)))
view.backgroundColor = UIColor.redColor()
let buttonHeight = 40
let buttonWidth = 40
let marginInterCell = 10
let marginInterRow = 20
let numberOfButtonsInRow = 300/(buttonWidth + marginInterCell)
let totalNumberOfButtons = 20
for index in 0..totalNumberOfButtons {
let button = UIButton(type: UIButtonType.System) as UIButton
button.titleLabel?.text = "\(index)"
let x = (index % numberOfButtonsInRow) * (buttonWidth + marginInterCell) + marginInterCell/2
let y = (buttonHeight + marginInterRow) * (index / numberOfButtonsInRow) + marginInterRow/2
button.backgroundColor = UIColor.greenColor()
button.frame = CGRect(origin: CGPoint(x: x, y: y), size: CGSize(width: buttonWidth, height: buttonHeight))
view.addSubview(button)
}

Related

In SpriteKit how can I have code for tracking the textures of two nodes at a time? As well code to track if all the nodes were matched in time?

I would like to have one piece of code in my app where I can track the textures of two nodes at a time. If the textures of the two nodes don't match I would like them reset back to their original state before the user touched them. On top of that i would like another piece of code for tracking if the particular node's textures were matched under a particular time frame like 90 seconds. Any tips on how I can do something like this for my app? Thanks.
Here is my current code:
import Foundation
import SpriteKit
class EasyScreen: SKScene {
override func didMove(to view: SKView) {
var background = SKSpriteNode(imageNamed: "Easy Screen Background")
let timerText = SKLabelNode(fontNamed: "Arial")
timerText.fontSize = 40
timerText.fontColor = SKColor.white
timerText.position = CGPoint(x: 20, y: 400)
timerText.zPosition = 1
var counter:Int = 90
timerText.run(SKAction.repeatForever(SKAction.sequence([SKAction.run {
counter-=1
timerText.text = " Time: \(counter)"
print("\(counter)")
if counter <= 0{
let newScene = TryAgainScreen(fileNamed: "Try Again Screen")
newScene?.scaleMode = .aspectFill
self.view?.presentScene(newScene)
}
},SKAction.wait(forDuration: 1)])))
background.position = CGPoint(x: 0, y: 0)
background.size.width = self.size.width
background.size.height = self.size.height
background.anchorPoint = CGPoint(x: 0.5,y: 0.5)
let matchCardOne = SKSpriteNode(imageNamed: "Fruit Match Card")
let matchCardTwo = SKSpriteNode(imageNamed: "Fruit Match Card")
let matchCardThree = SKSpriteNode(imageNamed: "Fruit Match Card")
let matchCardFour = SKSpriteNode(imageNamed: "Fruit Match Card")
matchCardOne.name = "FruitMatchCard1"
matchCardTwo.name = "FruitMatchCard2"
matchCardThree.name = "FruitMatchCard3"
matchCardFour.name = "FruitMatchCard4"
matchCardOne.size = CGSize(width: 150, height: 300)
matchCardTwo.size = CGSize(width: 150, height: 300)
matchCardThree.size = CGSize(width: 150, height: 300)
matchCardFour.size = CGSize(width: 150, height: 300)
matchCardOne.zPosition = 1
matchCardTwo.zPosition = 1
matchCardThree.zPosition = 1
matchCardFour.zPosition = 1
matchCardOne.anchorPoint = CGPoint(x: 0.5, y: 0.5)
matchCardTwo.anchorPoint = CGPoint(x: 0.5, y: 0.5)
matchCardThree.anchorPoint = CGPoint(x: 0.5, y: 0.5)
matchCardFour.anchorPoint = CGPoint(x: 0.5, y: 0.5)
matchCardOne.position = CGPoint(x: -125, y: 60)
matchCardTwo.position = CGPoint(x: -125, y: -260)
matchCardThree.position = CGPoint(x: 70, y: 60)
matchCardFour.position = CGPoint(x: 70 , y: -260)
addChild(background)
addChild(matchCardOne)
addChild(matchCardTwo)
addChild(matchCardThree)
addChild(matchCardFour)
addChild(timerText)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view?.isMultipleTouchEnabled = false
let touch = touches.first
let positionInSceneOne = touch!.location(in: self)
let tappedNodes = nodes(at: positionInSceneOne)
for node in tappedNodes{
if let tappedCard = node as? SKSpriteNode {
if tappedCard.name == "FruitMatchCard1" {
tappedCard.texture = SKTexture(imageNamed: "Apple")
}
}
let touchTwo = touches.first
let positionInSceneTwo = touch!.location(in: self)
let tappedNodesTwo = nodes(at: positionInSceneTwo)
for node in tappedNodesTwo{
if let tappedCard = node as? SKSpriteNode {
if tappedCard.name == "FruitMatchCard2" {
tappedCard.texture = SKTexture(imageNamed: "Apple")
}
}
let touchThree = touches.first
let positionInSceneThree = touch!.location(in: self)
let tappedNodesThree = nodes(at: positionInSceneThree)
for node in tappedNodesThree{
if let tappedCard = node as? SKSpriteNode {
if tappedCard.name == "FruitMatchCard3" {
tappedCard.texture = SKTexture(imageNamed: "Grapes")
}
}
let touchFour = touches.first
let positionInSceneFour = touch!.location(in: self)
let tappedNodesFour = nodes(at: positionInSceneFour)
for node in tappedNodesFour{
if let tappedCard = node as? SKSpriteNode {
if tappedCard.name == "FruitMatchCard4" {
tappedCard.texture = SKTexture(imageNamed: "Grapes")
}
}
}
}
}
}
}
}

Spritekit FPS drop problems

An app I'm building drops the FPS when sprite nodes are created, I have searched posts far and wide and cannot figure out why, if anyone had any ideas I would appreciate it!
The issues occur on the simulator and device.
the code for the creating of the nodes is below.
Thank you.
#objc func createEnemy(){
let randomDistribution = GKRandomDistribution(lowestValue: -350, highestValue: 350)
let sprite = SKSpriteNode(imageNamed: "Virus")
sprite.position = CGPoint(x: 700, y: randomDistribution.nextInt())
sprite.name = "Virus"
sprite.zPosition = 1
sprite.size = CGSize(width: 70, height: 70)
addChild(sprite)
sprite.physicsBody = SKPhysicsBody(texture: sprite.texture!, size: sprite.size)
sprite.physicsBody?.velocity = CGVector(dx: -500, dy: 0)
sprite.physicsBody?.linearDamping = 0
sprite.physicsBody?.contactTestBitMask = 1
sprite.physicsBody?.categoryBitMask = 0
sprite.physicsBody?.affectedByGravity = false
createBonus()
}
func createBonus(){
let randomDistribution = GKRandomDistribution(lowestValue: -350, highestValue: 350)
let sprite = SKSpriteNode(imageNamed: "Vaccine")
sprite.position = CGPoint(x: 700, y: randomDistribution.nextInt())
sprite.name = "Vaccine"
sprite.size = CGSize(width: 70, height: 70)
sprite.zPosition = 1
addChild(sprite)
sprite.physicsBody = SKPhysicsBody(texture: sprite.texture!, size: sprite.size)
sprite.physicsBody?.velocity = CGVector(dx: -500, dy: 0)
sprite.physicsBody?.linearDamping = 0
sprite.physicsBody?.contactTestBitMask = 1
sprite.physicsBody?.categoryBitMask = 0
sprite.physicsBody?.collisionBitMask = 0
sprite.physicsBody?.affectedByGravity = false
}
Did you try to preload the textures?
let image = SKTexture(imageNamed: "nodeImage")
override func didMove(to view: SKView) {
image.preload{
print("image has been preloaded")
}
}

Capturing MTKView texture to UIImageView efficiently

I want to capture the contents of the portion of an MTKView that has most recently updated into an UIImageView. I the following piece of code to accomplish this task:
let cicontext = CIContext(mtlDevice: self.device!) // set up once along with rest of renderPipeline
...
let lastSubStrokeCIImage = CIImage(mtlTexture: lastDrawableDisplayed.texture, options: nil)!.oriented(CGImagePropertyOrientation.downMirrored)
let bboxChunkSubCurvesScaledAndYFlipped = CGRect(...) // get bounding box of region just drawn
let imageCropCG = cicontext.createCGImage(lastSubStrokeCIImage, from: bboxStrokeAccumulatingScaledAndYFlipped)
// Now that we have a CGImage of just the right size, we have to do the following expensive operations before assigning to a UIIView
UIGraphicsBeginImageContextWithOptions(bboxStrokeAccumulating.size, false, 0) // open a bboxKeyframe-sized context
UIGraphicsGetCurrentContext()?.translateBy(x: 0, y: bboxStrokeAccumulating.height)
UIGraphicsGetCurrentContext()?.scaleBy(x: 1.0, y: -1.0)
UIGraphicsGetCurrentContext()?.draw(imageCropCG!, in: CGRect(x: 0, y: 0 , width: bboxStrokeAccumulating.width, height: bboxStrokeAccumulating.height))
// Okay, finally we create a CALayer to be a container for what we've just drawn
let layerStroke = CALayer()
layerStroke.frame = bboxStrokeAccumulating
layerStroke.contents = UIGraphicsGetImageFromCurrentImageContext()?.cgImage
UIGraphicsEndImageContext()
strokeView.layer.sublayers = nil // empty out strokeView
strokeView.layer.addSublayer(layerStroke) // add our hard-earned drawing in its latest state
So, this code works, but is not very efficient and makes the app lag when bboxStrokeAccumulating gets very large. Can anyone suggest more efficient alternatives?
For swift 4.0,
let lastDrawableDisplayed = metalView?.currentDrawable?.texture
if let imageRef = lastDrawableDisplayed?.toImage() {
let uiImage:UIImage = UIImage.init(cgImage: imageRef)
}
extension MTLTexture {
func bytes() -> UnsafeMutableRawPointer {
let width = self.width
let height = self.height
let rowBytes = self.width * 4
let p = malloc(width * height * 4)
self.getBytes(p!, bytesPerRow: rowBytes, from: MTLRegionMake2D(0, 0, width, height), mipmapLevel: 0)
return p!
}
func toImage() -> CGImage? {
let p = bytes()
let pColorSpace = CGColorSpaceCreateDeviceRGB()
let rawBitmapInfo = CGImageAlphaInfo.noneSkipFirst.rawValue | CGBitmapInfo.byteOrder32Little.rawValue
let bitmapInfo:CGBitmapInfo = CGBitmapInfo(rawValue: rawBitmapInfo)
let selftureSize = self.width * self.height * 4
let rowBytes = self.width * 4
let releaseMaskImagePixelData: CGDataProviderReleaseDataCallback = { (info: UnsafeMutableRawPointer?, data: UnsafeRawPointer, size: Int) -> () in
return
}
let provider = CGDataProvider(dataInfo: nil, data: p, size: selftureSize, releaseData: releaseMaskImagePixelData)
let cgImageRef = CGImage(width: self.width, height: self.height, bitsPerComponent: 8, bitsPerPixel: 32, bytesPerRow: rowBytes, space: pColorSpace, bitmapInfo: bitmapInfo, provider: provider!, decode: nil, shouldInterpolate: true, intent: CGColorRenderingIntent.defaultIntent)!
return cgImageRef
}
}
you can set the uiImage to your uiImageView

Migration from Swift 3 to Swift 4 Navigation Bar broken interface

I have migrated my app from Swift 3.1 to Swift 4.0 (Xcode 8.3.3 to Xcode 9.0) and some part of my interface is broken now. Navigation Bar of Navigation controller is complete mess. Please, look at screenshot:
There are 3 elements:
left Netfnet logo (image)
right Signal strength (image)
right QR Code button
As you can see, two images are too big and not in center and button was deformed (it should be perfect square, all images too).
There is code which generated navigation controller:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
settings()
}
func settings() {
let color = UIColor(red: 81 / 255, green: 155 / 255, blue: 22 / 255, alpha: 1.0)
self.navigationController?.navigationBar.barTintColor = color
let logoImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 35, height: 35))
logoImageView.contentMode = .scaleAspectFit
let logo = UIImage(named: "littleLogoImage")
logoImageView.image = logo
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: logoImageView)
let signalStengthImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 35, height: 35))
signalStengthImageView.contentMode = .scaleAspectFit
signalStengthImageView.image = UIImage(named: "signalStrength4")
let signalStengthImageItem = UIBarButtonItem(customView: signalStengthImageView)
let button = UIButton(type: .custom)
button.setImage(UIImage(named: "qrCodeButton"), for: .normal)
button.frame = CGRect(x: 0, y: 0, width: 35, height: 35)
let qrCodeButtonItem = UIBarButtonItem(customView: button)
navigationItem.rightBarButtonItems = [qrCodeButtonItem, signalStengthImageItem] //
}
}
I can decrease resolution of images directly myself, but I just don't get why everting was fine in Swift 3.1 and in Swift 4.0 is broken.
I will be thankful for any help or advice.
You have to add width and height constraints.
Your barImageView and barButton in CustomNavigationController should be like below :
func barImageView(imageName: String) -> UIBarButtonItem {
let imgView = imageView(imageName: imageName)
let widthConstraint = imgView.widthAnchor.constraint(equalToConstant: 35)
let heightConstraint = imgView.heightAnchor.constraint(equalToConstant: 35)
heightConstraint.isActive = true
widthConstraint.isActive = true
return UIBarButtonItem(customView: imgView)
}
func barButton(imageName: String, selector: Selector) -> UIBarButtonItem {
let button = UIButton(type: .custom)
button.setImage(UIImage(named: imageName), for: .normal)
button.frame = CGRect(x: 0, y: 0, width: 35, height: 35)
button.addTarget(self, action: selector, for: .touchUpInside)
let widthConstraint = button.widthAnchor.constraint(equalToConstant: 35)
let heightConstraint = button.heightAnchor.constraint(equalToConstant: 35)
heightConstraint.isActive = true
widthConstraint.isActive = true
return UIBarButtonItem(customView: button)
}
Your signalStengthImageView in LogoWithSignalStrength:
signalStengthImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 35, height: 35))
signalStengthImageView.contentMode = .scaleAspectFit
let widthConstraint = signalStengthImageView.widthAnchor.constraint(equalToConstant: 35)
let heightConstraint = signalStengthImageView.heightAnchor.constraint(equalToConstant: 35)
heightConstraint.isActive = true
widthConstraint.isActive = true
In Xcode 9, Navigation bar items are constraints base, Add this:
if #available(iOS 11.0, *) {
logoImageView.widthAnchor.constraint(equalToConstant: 35).isActive = true
logoImageView.heightAnchor.constraint(equalToConstant: 35).isActive = true
} else {
//set frames
}

UITextView in Swift2.2 shows Pixelated text, how do I regain the lost resolution?

Image of the pixelated text in the UITextView
Does anyone have any suggestions? The image of the issue is in the clickable link above.
Code:
struct Views {
static var name_field: UITextView?
}
In the viewDidLoad()
Views.name_field = UITextView(frame: CGRectMake(0, 0, name_field_width, 50))
Views.name_field!.textAlignment = NSTextAlignment.Center
Views.name_field!.font = UIFont.systemFontOfSize(15)
Views.name_field!.autocorrectionType = UITextAutocorrectionType.No
Views.name_field!.keyboardType = UIKeyboardType.Default
Views.name_field!.returnKeyType = .Done
Views.name_field!.delegate = self
Calling this function to style it
styleIt(Views.name_field!)
Adds a bottom border style and then sets the font, etc.
func styleIt(target: UITextView){
target.layer.backgroundColor = UIColor.clearColor().CGColor
let _border = CAShapeLayer()
_border.backgroundColor = UIColor.whiteColor().CGColor
_border.frame = CGRectMake(0, CGRectGetHeight(target.frame) - 1.0, CGRectGetWidth(target.frame), 1.0)
_border.shadowColor = UIColor.whiteColor().CGColor
_border.shadowOffset = CGSize(width: 3, height: 3)
_border.shadowOpacity = 0.23
_border.shadowRadius = 4
target.layer.addSublayer(_border)
target.font = UIFont(name: "ClementePDaa-Hairline", size: 24)
target.textColor = UIColor.whiteColor()
target.textContainerInset = UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 0)
applyPlaceholderStyle(target, placeholderText: _SEARCH_TEXT)
target.returnKeyType = .Done
target.frame = CGRectIntegral(target.frame)
target.layer.shouldRasterize = true
_border.shouldRasterize = true
target.textInputView.layer.shouldRasterize = true
}
This UITextView is a subview of search_field which is simply a UIView
search_field!.addSubview(Views.name_field!)
Your text view is blurry because the frame is using floating numbers.
To force integers value for your frame just do :
textView.frame = CGRectIntegral(textView.frame)

Resources