Show what image I am on in a UIScrollview swift - ios

Say I have 4 images that i download
I want to reverse the number of the image that I am on. Right now the image starts at 4/4 but I want it to read 1/4. So basically I am tying to reverse the numbers. This function is finding which number of the image that I am on. So the closer it get to the last image it turns the number to 1. I want the opposite effect. I want the number of the last image to turn to 4. So if i swipe right the number goes down from 4/4 to 3/4 to 2/4 to 1/4. But I want the first image to be 1 not 4 so it goes 1/4 to 2/4 to 3/4 to 4/4.
Here is how I am doing it:
//MARK: Set up and download Promotions
var numberPromotions = 0;
var imageSize = 0;
private var promos = Array<(picture: String, path: String)>()
func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
print("Scroll finished")
print("My promot gus" , self.numberPromotions)
print("Scroll number", scrollView.contentOffset.x)
print("IMAGE size " , self.imageSize)
var myPlace : Double = 0
var totalSize : Double = 0
let scrollviewOffset = Double(scrollView.contentOffset.x)
print("int Scroview " , scrollviewOffset)
totalSize = Double(self.imageSize * (numberPromotions - 1))
print("To;tal size" , totalSize)
if scrollviewOffset == 0 {
myPlace = Double(numberPromotions)
}else
{
myPlace = Double(totalSize / scrollviewOffset)
print("Gus Place" , myPlace)
}
print(myPlace % 1 == 0.5)
if myPlace % 1 == 0.5
{
print("Not a whole number Adding 0.5")
myPlace = myPlace + 0.5
}
print("My place", myPlace)
var myString : String
let myPlaceString = String(Int(myPlace))
myString = myPlaceString + "/" + String(numberPromotions)
numOfPromoLabel.text = myString
}

Try this:
myString = (String(numberPromotions)-myPlaceString + 1) + "/" + String(numberPromotions)

Related

How to replace a word in a string if it contains any words from an array [duplicate]

This question already has answers here:
Replace multiple words from a String based on the values in an Array
(4 answers)
Closed 3 years ago.
I'd like to find and replace any word(s) in a string that match any string value in an array. I can find the matching value using .contains(where:
var playersApprovedArray = ["Monica","Zach","Chrissy"]
card.cardText = "Chrissy, do 10 jumping jacks right now!"
if playersApprovedArray.contains(where: card.cardText.contains) {
print("Found matching player in card text")
// Replace the matching word/player here with another word/player
}
But I don't know how to replace the occurrence of the matching word with another string value in the array.
Here is a simple solution that replaces one player with another:
for i in playersApprovedArray.indices {
let player = playersApprovedArray[i]
if let range = cardText.range(of: player) {
let otherIndex = (i + Int.random(in: 1..<playersApprovedArray.count)) % playersApprovedArray.count
let otherPlayer = playersApprovedArray[otherIndex]
cardText.replaceSubrange(range, with: otherPlayer)
break
}
}
You can remove the break if the sentence may contains more players.
Here is a faster solution that would replace all occurrences of any player's name by another:
let playersApprovedArray = ["Monica","Zach","Chrissy"]
let cardText = " Chrissy, do 10 jumping jacks right now! "
var result = ""
var i = cardText.startIndex
while i < cardText.endIndex {
var j = i
while j < cardText.endIndex,
CharacterSet.letters.inverted.isSuperset(of: CharacterSet(charactersIn: String(cardText[j])))
{
j = cardText.index(after: j)
}
var tempo1 = ""
if i != j { tempo1 += cardText[i..<j] }
if j < cardText.endIndex { i = j } else {
result += tempo1
break
}
while j < cardText.endIndex,
CharacterSet.letters.isSuperset(of: CharacterSet(charactersIn: String(cardText[j])))
{
j = cardText.index(after: j)
}
let tempo2 = String(cardText[i..<j])
if let index = playersApprovedArray.firstIndex(of: tempo2) {
let otherIndex = (index + Int.random(in: 1..<playersApprovedArray.count)) % playersApprovedArray.count
let otherPlayer = playersApprovedArray[otherIndex]
result += tempo1 + otherPlayer
//See comment below for possible early exit
} else {
result += tempo1 + tempo2
}
i = j
}
print(result) // Monica, do 10 jumping jacks right now!
If you're sure that there is only one player in the string, then you can exit early this way:
...
result += tempo1 + otherPlayer + cardText[j...]
break
...

Making a binary calculator app (swift)

For a project in Uni I decided to make a binary calculator app to learn a little bit more about coding.
I've come as far as completing a regular calculator app (but it only has two numbers: 1 ; 0) but I can't figure out how to make the calculator work like it should ( 1010 + 1101 = 10111 not 2111). All help is appreciated.
var numberEkraanil:Double = 0;
var eelmineNumber:Double = 0;
var tehesmatemaatikat = false
var operation = 0;
#IBOutlet weak var label: UILabel!
#IBAction func Numbers(_ sender: UIButton) {
if tehesmatemaatikat == true
{
label.text = String(sender.tag-1)
numberEkraanil = Double(label.text!)!
tehesmatemaatikat = false
}
else
{
label.text = label.text! + String(sender.tag-1)
numberEkraanil = Double(label.text!)!
}
}
#IBAction func nupud(_ sender: UIButton) {
if label.text != "" && sender.tag != 6 && sender.tag != 8
{
eelmineNumber = Double(label.text!)!
if sender.tag == 3 //Liitmine
{
label.text = "+";
}
else if sender.tag == 4 //Lahutamine
{
label.text = "-";
}
else if sender.tag == 5 // Korrutamine
{
label.text = "x";
}
else if sender.tag == 7 // Jagamine
{
label.text = "รท";
}
operation = sender.tag
tehesmatemaatikat = true;
}
else if sender.tag == 8
{
if operation == 3
{
label.text = String(eelmineNumber + numberEkraanil)
}
else if operation == 4
{
label.text = String(eelmineNumber - numberEkraanil)
}
else if operation == 5
{
label.text = String(eelmineNumber * numberEkraanil)
}
else if operation == 7
{
label.text = String(eelmineNumber / numberEkraanil)
}
}
else if sender.tag == 6
{
label.text = ""
eelmineNumber = 0;
numberEkraanil = 0;
operation = 0;
}
You can possibly convert binary numbers to decimal numbers. For example turn "1010" into int "10" and then reverse the process to get the binary again. In your example "1010 + 1101 = 10111" you can convert "1010" and into "10" and "13", make the ordinary calculation with those decimals and convert the result "23", which will give you "23".
But of course there are other ways. This website can help you with binary calculation. It's a math website: http://www.calculator.net/binary-calculator.html.
You will need to write a base 10 to base 2 and a base 2 to base 10 converter. Here is pseudo-code for both:
To convert a binary string to an integer, do the following:
Seed a result value to zero.
while your input string is not empty:
shift the result value 1 bit to the left
remove the left-most character from your input string, and if it's a 1, add 1 to your result value.
To convert an int to a binary string, do the same in reverse:
Copy your int to a scratch variable, scratch.
Set your output string to an empty string.
While scratch is not 0:
if scratch && 1 is 0, append a "0" to the left of your output string
if scratch && 1 is 1, append a "1" to the left of your output string
shift scratch 1 bit to the right
Once you have those building-blocks getting your calculator to work is pretty straightforward. When the user inputs a binary string, convert it to an integer working value. Do your calculations on integer values, and then convert the integer result to a binary string for display.

Use of unresolved identifer for data storage in Swift 3

Help with this swift 3 error. We are trying to somehow store the number of characters in each phrase, in this case into anagram1length and anagram2length as per source that comes from https://www.raywenderlich.com/77981/make-letter-word-game-uikit-swift-part-1. Concern here is the following two lines of code in swift 3 giving us an error use of unresolved identifier 'count':
let anagram1length = count(anagram1)
let anagram2length = count(anagram2)
From the following function:
func dealRandomAnagram () {
//1
assert(level.anagrams.count > 0, "no level loaded")
//2
let randomIndex = randomNumber(minX:0, maxX:UInt32(level.anagrams.count-1))
let anagramPair = level.anagrams[randomIndex]
//3
let anagram1 = anagramPair[0] as! String
let anagram2 = anagramPair[1] as! String
//4
let anagram1length = count(anagram1)
let anagram2length = count(anagram2)
//5
print("phrase1[\(anagram1length)]: \(anagram1)")
print("phrase2[\(anagram2length)]: \(anagram2)")
//calculate the tile size
let tileSide = ceil(ScreenWidth * 0.9 / CGFloat(max(anagram1length, anagram2length))) - TileMargin
//get the left margin for first tile
var xOffset = (ScreenWidth - CGFloat(max(anagram1length, anagram2length)) * (tileSide + TileMargin)) / 2.0
//adjust for tile center (instead of the tile's origin)
xOffset += tileSide / 2.0
//initialize target list
targets = []
//create targets
for (index, letter) in anagram2length.enumerate(anagram2) {
if letter != " " {
let target = TargetView(letter: letter, sideLength: tileSide)
target.center = CGPointMake(xOffset + CGFloat(index)*(tileSide + TileMargin), ScreenHeight/4)
gameView.addSubview(target)
targets.append(target)
}
}
The tutorial is obviously written in an old Swift version.
In the current Swift 3 version it's usually
let anagram1length = anagram1.characters.count
let anagram2length = anagram2.characters.count

UISlider ValueChanged action not working

I want to calculate a number in real-time with UISlider, this is my method:
#IBAction func HPsliderValueChanged(_ sender: CustomUISlider) {
calculator.HPPercentage = Double(HPSlider.value)
HPValue.text = String(Int(HPSlider.value * 100)) + " %"
resultLabel.text = String(calculator.calculate())
}
Both the HPValue label and resultLabel are expected to change value when user swipes on slider, however, now only HPValue label changes, the resultLabel doesn't work.
calculator is not nil, here's its code:
class TurretDiveCalculator {
var hero: Heroes = .taka
var build = [DefenseItems](repeatElement(DefenseItems(name: "Empty Item", index: 0, price: 0, image: #imageLiteral(resourceName: "EmptyItem")), count: 6))
var HPPercentage: Double = 0
func calculate() -> Int {
let baseHP = hero.HPLow + (hero.HPHigh - hero.HPLow) / 12 * Double(hero.level)
let baseDefense = hero.armorLow + (hero.armorHigh - hero.armorLow) / 12 * Double(hero.level) + hero.shieldLow + (hero.shieldHigh - hero.shieldLow) / 12 * Double(hero.level)
var buildHP = 0.0
var buildDefense = 0.0
for item in build {
buildDefense += item.armor
buildDefense += item.shield
buildHP += item.HP
}
let fullHP = baseHP + buildHP
var HP = fullHP
let defense = baseDefense + buildDefense
var numberOfShots = 0
while HP > 0 {
let perShotDamageRaw: Double = 330 + Double(numberOfShots) * 0.09 * fullHP
let mitigatedDamage: Double = 0.09 * perShotDamageRaw + 0.9 * perShotDamageRaw / (100 + defense) * 100
HP -= mitigatedDamage
numberOfShots += 1
}
return numberOfShots
}
}
How do I get resultLabel's value to change in real-time, too?
As can be seen in the chat, we managed to find the problem.
This answer is just some general debugging tips and tricks when a problem like this arises.
The original problem was:
now only HPValue label changes, the resultLabel doesn't work.
Lets find out where the problem is. Here's the code:
resultLabel.text = String(calculator.calculate())
Two things can go wrong here:
The resultLabel is not properly wired. To see if that is the case, try setting the value to a plain ol' string and see if you can see that. I you can, well, the textfield is wired properly.
The calculate() method returns an unexpected value. Try verifying what the method returns by adding a print statement just before the return
And as you can see in the chat, once we'd isolated where the problem occurred it was easier for #bright-future to track down the issue.
Hope this helps anybody when they are trying to debug a problem :)

Most effecient way to calculate this in swift (simple math)

The question is related to calculating an increase in currency.
Loop over this n times, and let's say you start with $50k and your multiplier is 2. Something like b * 2 + a
This is the correct result:
$50,000.00
$100,000.00
$250,000.00
$600,000.00
$1,450,000.00
$3,500,000.00
$8,450,000.00
$20,400,000.00
$49,250,000.00
So just to be clear, the question is about efficiency in swift, not simply how to calculate this. Are there any handy data structures that would make this faster? Basically I was just looping through how many years (n) adding 2 (200%) and incrementing a couple temp variables to keep track of the current and previous values. It feels like there has got to be a much better way of handling this.
$50k base
$50k * 2 + 0 (previous value) = $100k
$100k * 2 + $50k = $250k
$250k * 2 + $100k = $600k
etc.
Code:
let baseAmount = 50000.0
let percentReturn = 200.0
let years = 10
// Calc decimal of percent.
var out: Double = 0.0
var previous: Double = 0.0
let returnPercent = percentReturn * 0.01
// Create tmp array to store values.
var tmpArray = [Double]()
// Loop through years.
for var index = 0; index < years; ++index
{
if index == 0
{
out = baseAmount
tmpArray.append(baseAmount)
}
else if index == 1
{
out = (out * returnPercent)
tmpArray.append(out)
previous = baseAmount
}
else
{
let tmp = (tmpArray.last! * returnPercent) + previous
previous = tmpArray.last!
tmpArray.append(tmp)
}
}
println(tmpArray)
Here are some ideas for improving efficiency:
Initialize your array to the appropriate size (it isn't dynamic; it is always the number of years)
Remove special cases (year 0 and 1 calculations) from the for-loop
Code:
func calculate(baseAmount: Double, percentReturn: Double, years: Int) -> [Double] {
// I prefer to return an empty array instead of nil
// so that you don't have to check for nil later
if years < 1 {
return [Double]()
}
let percentReturnAsDecimal = percentReturn * 0.01
// You know the size of the array, no need to append
var result = [Double](count: years, repeatedValue: 0.0)
result[0] = baseAmount
// No need to do this in the loop
if years > 1 {
result[1] = baseAmount * percentReturnAsDecimal
}
// Loop through years 2+
for year in 2 ..< years {
let lastYear = result[year - 1]
let yearBeforeLast = result[year - 2]
result[year] = (lastYear * percentReturnAsDecimal) + yearBeforeLast
}
return result
}
Efficiency in terms of speed I found this to be the fastest implementation of your algorithm:
let baseAmount = 50000.0
let returnPercent = 2.0
let years = 10
// you know the size of the array so you don't have to append to it and just use the subscript which is much faster
var array = [Double](count: years, repeatedValue: 0)
var previousValue = 0.0
var currentValue = baseAmount
for i in 0..<years {
array[i] = currentValue
let p2 = currentValue
currentValue = currentValue * returnPercent + previousValue
previousValue = p2
}
print(array)

Resources