Swift Change UIView Image - ios

I am trying to make a basic game for iOS10 using swift 3 and scenekit. In one part of my games code I have a function that adds fishes to the screen, and gives each one a certain tag so i can find them later:
let fish = UIImageView(frame: CGRect(x: 0, y: 0, width: CGFloat(fishsize.0), height: CGFloat(fishsize.1)))
fish.contentMode = .scaleAspectFit
fish.center = CGPoint(x: CGFloat(fishsize.0) * -0.6, y: pos)
fish.animationImages = fImg(Fishes[j].size, front: Fishes[j].front)
fish.animationDuration = 0.7
fish.startAnimating()
fish.tag = j + 200
self.view.insertSubview(fish, belowSubview: big1)
What I would like is to be able to, at a certain point, recall the fish and
Change the images shown, and
Stop the animation.
Is this possible? I've been trying it with var fish = view.viewWithTag(killer+200)! but from this I can't seem to change any image properties of the new variable fish.
Any help would be much appreciated.
Tom

Try to cast the UIView to UIImageView like this.
if let fish = view.viewWithTag(killer+200) as? UIImageView {
//Perform your action on imageView object
}

Related

Drawing a circular loader

I have to create a circular loader as per below image (Front is thicker than tail)
I am able to create a circular progress bar and also provided rotation animation.
below is code for circle
func circleFrame() -> CGRect {
var circleFrame = CGRect(x: 0, y: 0, width: 2 * circleRadius, height: 2 * circleRadius)
let circlePathBounds = circlePathLayer.bounds
circleFrame.origin.x = circlePathBounds.midX - circleFrame.midX
circleFrame.origin.y = circlePathBounds.midY - circleFrame.midY
return circleFrame
}
func circlePath() -> UIBezierPath {
return UIBezierPath(ovalIn: circleFrame())
}
Using above code I can create a circle of equal width but not like as displayed image.
Please guide me how to create a loader like above image (tail is thinner than front). Any idea or suggestion would be great.
The simplest approach might be to create the image you want to display and then rotate it, rather than trying to draw it from scratch.
I haven't tried the following tutorial but I'm including it as a sample of how this might be done:
https://bencoding.com/2015/07/27/spinning-uiimageview-using-swift/
Note that the GitHub version (linked on that page) includes a Swift 4 update.

How to create a ring with 3D effect using Sprite Kit?

I want to create a ring with a 3D effect using Sprite Kit. (SEE IMAGES)
I tried subclassing a SKNode and adding two nodes as children. (SEE CODE)
One node was a complete SKShapeNode ellipse, and the other was half ellipse using SKCropNode with a higher zPosition.
It looks good, but the SKCropNode increases the app CPU usage from 40% to 99%.
Any ideas on how to reduce the SKCropNode performance cost, or any alternative to create the same ring 3D effect?
class RingNode: SKNode {
let size: CGSize
init(size: CGSize, color: SKColor)
{
self.size = size
self.color = color
super.init()
ringPartsSetup()
}
private func ringPartsSetup() {
// LEFT PART (half ellipse)
let ellipseNodeLeft = getEllipseNode()
let leftMask = SKSpriteNode(texture: nil, color: SKColor.blackColor(), size: CGSize(
width: ellipseNodeLeft.frame.size.width/2,
height: ellipseNodeLeft.frame.size.height))
leftMask.anchorPoint = CGPoint(x: 0, y: 0.5)
leftMask.position = CGPoint(x: -ellipseNodeLeft.frame.size.width/2, y: 0)
let leftNode = SKCropNode()
leftNode.addChild(ellipseNodeLeft)
leftNode.maskNode = leftMask
leftNode.zPosition = 10 // Higher zPosition for 3D effect
leftNode.position = CGPoint(x: -leftNode.frame.size.width/4, y: 0)
addChild(leftNode)
// RIGHT PART (complete ellipse)
let rightNode = getEllipseNode()
rightNode.position = CGPoint(x: 0, y: 0)
rightNode.zPosition = 5
addChild(rightNode)
}
private func getEllipseNode() -> SKShapeNode {
let ellipseNode = SKShapeNode(ellipseOfSize: CGSize(
width: size.width,
height: size.height))
ellipseNode.strokeColor = SKColor.blackColor()
ellipseNode.lineWidth = 5
return ellipseNode
}
}
You've got the right idea with your two-layer approach and the half-slips on top. But instead of using a shape node inside a crop node, why not just use a shape node whose path is a half-ellipse? Create one using either CGPath or UIBezierPath API — use a circular arc with a transform to make it elliptical — then create your SKShapeNode from that path.
You may try converting your SKShapeNode to an SKSpriteNode. You can use SKView textureFromNode: (but we aware of issues with scale that require you to use it only after the node has been added to the view and at least one update cycle has run), or from scratch using an image (created programatically with a CGBitmapContext, of course).

Using variables in CGRectMake, Swift, UIkit

For an App I'm making i need to use variables to change the size and position of objects (Labels). I've tried var example = CGRectMake(0, 0, 0, 100), hoping it would ignore the zeros (Not really thinking it would though). I then tried:
var example = 100
Label1.frame = CGRectMake(20, 20, 50, example)
I changed the syntax a bit, adding "" and replacing the CGRectMake with CGRect etc, but nothing worked... I don't get what I'm doing wrong here... Help!
Below is the new syntax used since Swift 3.
CGRect(x: 0, y: 0, width: 100, height: 100)
CGRectMake takes CGFloats for all of its arguments. Your sample code should work fine if you specify that example is supposed to be a CGFloat, using a type identifier:
// v~~~~ add this...
var example: CGFloat = 100
Label1.frame = CGRectMake(20, 20, 50, example)
Otherwise, swift infers the type of example to be Int, and the call to CGRectMake fails, cuz it can't take an Int as a parameter...
So, there is many ways to skin the cat. It all depends what your needs and requirements are (maybe you could elaborate a bit on what you are trying to achieve?). But one way to do it could be to set a variable when something happens, and then update the frame of the label. If you added a tap gesture recognizer to your view, and updated your label like so:
let myLabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
let tapGestRecog = UITapGestureRecognizer(target: self, action: "handleTap:")
self.view.addGestureRecognizer(tapGestRecog)
}
func handleTap(sender:UIGestureRecognizer) {
let newXposition = sender.locationInView(self.view).x
let newYposition = sender.locationInView(self.view).y
myLabel.frame = CGRectMake(newXposition, newYposition, 200, 200)
}
This is just an example, and a very crude way of doing it. There are many other ways of doing it, but it hopefully gives you an idea of how to achieve it.
Swift allows syntax that Objective-C does not:
var example = 100
label.frame.size.height = example
In objective-C you would have to do it differently:
CGRect frame = label.frame; //Create a temporary rect to hold the frame value
frame.size.height = example;
label.frame = frame;

cocos2d swift how to show a sprite?

So I have my scene presenting and am trying to display a sprite when I press a button. I know the function is called because of a NSLog but I can't get the sprite to show.
func ShowShip() {
var booster = CCBReader.load("ccbResources/Booster")
booster.position = CGPoint(x: 0, y: 0)
self.addChild(booster)
NSLog("created sprite")
}
The log is called but the sprite isn't displayed. I looked at the quickstart tutorial and couldn't see much difference.
edit: tried calling the .png resource directly but got unwrapping error
Try direct method:
//method_1 : read image from disk
var booster = CCSprite(imageNamed:"Booster.png")
booster.position = CGPoint(x: 50, y: 50)
self.addChild(booster, z:3)
//method_2 : read image from sprite sheet
var frame1 = CCSpriteFrameCache.sharedSpriteFrameCache().spriteFrameByName("Booster.png") as CCSpriteFrame
var booster = CCSprite(spriteFrame: frame1)
booster.position = CGPoint(x: 50, y: 50)
self.addChild(booster, z:3)

Batch variable creation in Swift

So im writing my first lines of code in Swift, and i want to make a game where you need to tilt the device to make a gravity shift and by doing so make a ball drop to the floor while maneuvering around obstacles.
Ive been looking up different methods, and I found one where you can make the obstacles by just using let, For example (Im using UIKit)
let barrier1 = UIView(frame: CGRect(x: 0, y: 300, width: 20, height: 20))
barrier1.backgroundColor = UIColor.redColor()
view.addSubview(barrier1)
Its quite a bit of code to declare every barrier this way, and I was hoping if there was a way of doing this in a while loop where every time the loop runs, x = x + 1 is stated and you make variables that way in batch. Can anyone help me? Thanks!
This is what arrays are for. Declare a variable called barriers of type [UIView] and then append each new barrier to this array.
var barriers:[UIView] = []
for i in 1...20 {
let newbarrier = UIView(frame: CGRect(x: 0, y: 300 + i * 30, width: 20, height: 20))
newbarrier.backgroundColor = UIColor.redColor()
view.addSubview(newbarrier)
barriers.append(newbarrier)
}
// Now you can refer to each barrier by its index: barriers[0], barriers[1]
// up to barriers[19]

Resources