"Cannot assign to property: "any" is immutable" error - ios

tiledViewsStack contains UIImageViews. I'm trying to give each UIImageView in the array a new center coordinate. Not sure why I'm getting this error for the last line in the for loop...
var tiledViewsStack = [AnyObject]()
var randLocInt = Int()
var randLoc = CGPoint()
for var any in tiledViewsStack
{
randLocInt = Int((arc4random()*10) % 9) // 0, --- 8
randLoc = allCenters[randLocInt].CGPointValue()
any.center = randLoc
}

Needed to make tiledViewsStack a stack of UIImages, not AnyObjects. Changed var tiledViewsStack = [AnyObject]() to var tiledViewsStack = [UIImageView]().

When you use Anyobject, you are using a protocol.
It can be an istance of any type.
So AnyObject can represent an Int, a Float, a String, a UIView, anything.
The array [AnyObject] is a nonspecific type to represent any type of class. In you code you initialize an always immutable array, and when you try to modify each element you get the error..
The correct way to declare and initialize a type of this array is:
var genericTypeArray : [AnyObject] = [1, true, 1.2, "hello"]
For you code, you must change :
var tiledViewsStack = [AnyObject]()
with a code like my example up, or you modify AnyObject class with a specified class like UIImageView as recommended in comments.

Related

Trouble instantiating an object via init() method passing in an Array of Dictionaries

I'm using Swift to create an NSObject by its init() method, passing in strings and an array of Dictionaries (the Dictionaries represent UIButtons, each with a title, a link, a blurb for each potential button - there can be from 1-3 of these buttons).
In the init() method of ContentItem() I'm trying to create Dictionaries as properties of this object.
It is giving me an error: "Instance member 'subscript' cannot be used on type "(String: String)" on the line: "var tempButton = [String: String][]".
I did some research and it sounds like it might be to do with instantiating variables in the init() method - because this is before the object has been created?
Is this correct? Anyone have any insight into this? Is there a way to just map these passed in arguments to the class? I'm stuck. Thanks.
class ContentItem: NSObject {
var title: String
var body: String
var buttonsArray: Array<Dictionary<String,String>>
init?(title: String, body: String, buttonsArgs: Array<Dictionary<String, String>>) {
self.title = title
self.body = body
for btn in buttonsArgs {
var tempButton = [String: String][] // placeholder for the button we are creating to attach to buttonsArray[]
for (btnKey, btnValue) in btn { // iterate through each button's Dictionary element that is passed in to init()
print("btnKey: \(btnKey), btnValue: \(btnValue)")
tempButton[btnKey] = btnValue // assembling the parameters of this button
}
self.buttonsArray.append(tempButton) // assigning the buttons to the object
}
super.init()
}
}
Issue 1
Function calls are always done with the ( ), not [ ]:
var tempButton = [String: String]()
Which is equivalent to:
var tempButton: Dictionary<String, String> = Dictionary<String, String>.init()
Issue 2
You're attempting to append to an array that doesn't exist:
var buttonsArray: Array<Dictionary<String,String>>
That line declares that a variable called buttonsArray will exist, of type Array<Dictionary<String,String>>, but it doesn't define any values for it. Change it to this instead:
var buttonsArray: Array<Dictionary<String,String>> = Array<Dictionary<String,String>>()
And now that there is an initialization occuring, the compiler can infer the type for us:
var buttonsArray = Array<Dictionary<String,String>>()
And we can use the shorthand for Array<Dictionary<String,String>>, [[String : String]];
var buttonsArray = [[String : String]]()

Swift - Array of Any to Array of Strings

How can I cast an array initially declared as container for Any object to an array of Strings (or any other object)?
Example :
var array: [Any] = []
.
.
.
array = strings // strings is an array of Strings
I receive an error : "Cannot assign value of type Strings to type Any"
How can I do?
You can't change the type of a variable once it has been declared, so you have to create another one, for example by safely mapping Any items to String with flatMap:
var oldArray: [Any] = []
var newArray: [String] = oldArray.flatMap { String($0) }
Updated to Swift 5
var arrayOfAny: [Any] = []
var arrayOfStrings: [String] = arrayOfAny.compactMap { String(describing: $0) }
You can use this synatic sugar grammar. Still one line of code :)
var arr: [Any] = []
var strs = [String]()
arr = strs.map {$0 as! [String]}

Filter NSMutableArray data by value into object in Swift

I have this problem
I'm using Swift 2.0 in my project for iOS 9. I've created an object like this:
public class element_x: NSObject{
var name: String!
var description_element: String!
}
So, In a method I declare two NSMutableArray: 1) for all data and 2) for filter data, like this:
var original = NSMutableArray()
var filtered = NSMutableArray()
And during the process I populate this NSMutableArray like this:
let custom_object = element_x()
self.original.addObject(custom_object);
My question is: how can I filter original array by name value and saved in filtered array?
You don't have to use NSMutableArray. The native Array type in Swift is very capable. You can declare it mutable with var (equivalent to NSMutableArray) or constant with let (same as NSArray):
public class element_x: NSObject{
var name: String!
var description_element: String!
}
// Declare an array containing elements of element_x type
var original = [element_x]()
var filtered = [elememt_x]()
let custom_object = element_x()
self.original.append(custom_object)
// Find all elements with name == "david"
self.filtered = self.original.filter { $0.name == "david" }

How to create an empty array in Swift?

I'm really confused with regards to how we create an empty array in Swift. Could you please show me the different ways we have to create an empty array with some detail?
Here you go:
var yourArray = [String]()
The above also works for other types and not just strings. It's just an example.
Adding Values to It
I presume you'll eventually want to add a value to it!
yourArray.append("String Value")
Or
let someString = "You can also pass a string variable, like this!"
yourArray.append(someString)
Add by Inserting
Once you have a few values, you can insert new values instead of appending. For example, if you wanted to insert new objects at the beginning of the array (instead of appending them to the end):
yourArray.insert("Hey, I'm first!", atIndex: 0)
Or you can use variables to make your insert more flexible:
let lineCutter = "I'm going to be first soon."
let positionToInsertAt = 0
yourArray.insert(lineCutter, atIndex: positionToInsertAt)
You May Eventually Want to Remove Some Stuff
var yourOtherArray = ["MonkeysRule", "RemoveMe", "SwiftRules"]
yourOtherArray.remove(at: 1)
The above works great when you know where in the array the value is (that is, when you know its index value). As the index values begin at 0, the second entry will be at index 1.
Removing Values Without Knowing the Index
But what if you don't? What if yourOtherArray has hundreds of values and all you know is you want to remove the one equal to "RemoveMe"?
if let indexValue = yourOtherArray.index(of: "RemoveMe") {
yourOtherArray.remove(at: indexValue)
}
This should get you started!
There are four ways to create a empty array in Swift 5 and shorthand syntax way is always preferred.
Method 1: Shorthand Syntax
var arr = [Int]()
Method 2: Array Initializer
var arr = Array<Int>()
Method 3: Array with an Array Literal
var arr:[Int] = []
Method 4: Credit goes to #BallpointBen
var arr:Array<Int> = []
var myArr1 = [AnyObject]()
can store any object
var myArr2 = [String]()
can store only string
You could use
var firstNames: [String] = []
There are 2 major ways to create/intialize an array in swift.
var myArray = [Double]()
This would create an array of Doubles.
var myDoubles = [Double](count: 5, repeatedValue: 2.0)
This would create an array of 5 doubles, all initialized with the value of 2.0.
If you want to declare an empty array of string type you can do that in 5 different way:-
var myArray: Array<String> = Array()
var myArray = [String]()
var myArray: [String] = []
var myArray = Array<String>()
var myArray:Array<String> = []
Array of any type :-
var myArray: Array<AnyObject> = Array()
var myArray = [AnyObject]()
var myArray: [AnyObject] = []
var myArray = Array<AnyObject>()
var myArray:Array<AnyObject> = []
Array of Integer type :-
var myArray: Array<Int> = Array()
var myArray = [Int]()
var myArray: [Int] = []
var myArray = Array<Int>()
var myArray:Array<Int> = []
Here are some common tasks in Swift 4 you can use as a reference until you get used to things.
let emptyArray = [String]()
let emptyDouble: [Double] = []
let preLoadArray = Array(repeating: 0, count: 10) // initializes array with 10 default values of the number 0
let arrayMix = [1, "two", 3] as [Any]
var arrayNum = [1, 2, 3]
var array = ["1", "two", "3"]
array[1] = "2"
array.append("4")
array += ["5", "6"]
array.insert("0", at: 0)
array[0] = "Zero"
array.insert(contentsOf: ["-3", "-2", "-1"], at: 0)
array.remove(at: 0)
array.removeLast()
array = ["Replaces all indexes with this"]
array.removeAll()
for item in arrayMix {
print(item)
}
for (index, element) in array.enumerated() {
print(index)
print(element)
}
for (index, _) in arrayNum.enumerated().reversed() {
arrayNum.remove(at: index)
}
let words = "these words will be objects in an array".components(separatedBy: " ")
print(words[1])
var names = ["Jemima", "Peter", "David", "Kelly", "Isabella", "Adam"]
names.sort() // sorts names in alphabetical order
let nums = [1, 1234, 12, 123, 0, 999]
print(nums.sorted()) // sorts numbers from lowest to highest
Array in swift is written as **Array < Element > **, where Element is the type of values the array is allowed to store.
Array can be initialized as :
let emptyArray = [String]()
It shows that its an array of type string
The type of the emptyArray variable is inferred to be [String] from the type of the initializer.
For Creating the array of type string with elements
var groceryList: [String] = ["Eggs", "Milk"]
groceryList has been initialized with two items
The groceryList variable is declared as “an array of string values”, written as [String].
This particular array has specified a value type of String, it is allowed to store String values only.
There are various properities of array like :
- To check if array has elements (If array is empty or not)
isEmpty property( Boolean ) for checking whether the count property is equal to 0:
if groceryList.isEmpty {
print("The groceryList list is empty.")
} else {
print("The groceryList is not empty.")
}
- Appending(adding) elements in array
You can add a new item to the end of an array by calling the array’s append(_:) method:
groceryList.append("Flour")
groceryList now contains 3 items.
Alternatively, append an array of one or more compatible items with the addition assignment operator (+=):
groceryList += ["Baking Powder"]
groceryList now contains 4 items
groceryList += ["Chocolate Spread", "Cheese", "Peanut Butter"]
groceryList now contains 7 items
As per Swift 5
// An array of 'Int' elements
let oddNumbers = [1, 3, 5, 7, 9, 11, 13, 15]
// An array of 'String' elements
let streets = ["Albemarle", "Brandywine", "Chesapeake"]
// Shortened forms are preferred
var emptyDoubles: [Double] = []
// The full type name is also allowed
var emptyFloats: Array<Float> = Array()
you can remove the array content with passing the array index or you can remove all
var array = [String]()
print(array)
array.append("MY NAME")
print(array)
array.removeFirst()
print(array)
array.append("MY NAME")
array.removeLast()
array.append("MY NAME1")
array.append("MY NAME2")
print(array)
array.removeAll()
print(array)
Swift 5
// Create an empty array
var emptyArray = [String]()
// Add values to array by appending (Adds values as the last element)
emptyArray.append("Apple")
emptyArray.append("Oppo")
// Add values to array by inserting (Adds to a specified position of the list)
emptyArray.insert("Samsung", at: 0)
// Remove elements from an array by index number
emptyArray.remove(at: 2)
// Remove elements by specifying the element
if let removeElement = emptyArray.firstIndex(of: "Samsung") {
emptyArray.remove(at: removeElement)
}
A similar answer is given but that doesn't work for the latest version of Swift (Swift 5), so here is the updated answer. Hope it helps! :)
Initiating an array with a predefined count:
Array(repeating: 0, count: 10)
I often use this for mapping statements where I need a specified number of mock objects. For example,
let myObjects: [MyObject] = Array(repeating: 0, count: 10).map { _ in return MyObject() }
Compatible with: Xcode 6.0.1+
You can create an empty array by specifying the Element type of your array in the declaration.
For example:
// Shortened forms are preferred
var emptyDoubles: [Double] = []
// The full type name is also allowed
var emptyFloats: Array<Float> = Array()
Example from the apple developer page (Array):
Hope this helps anyone stumbling onto this page.
Swift 5 version:
let myArray1: [String] = []
let myArray2: [String] = [String]()
let myArray3 = [String]()
let myArray4: Array<String> = Array()
Or more elegant way:
let myElegantArray1: [String] = .init()
extension Array {
static func empty() -> Self {
return []
}
}
let myElegantArray2: [String] = .empty()
The extension above, you can use for any type Array

Crash while getting value from the dictionary in Swift

I have created a dictionary like
var tempArray1 = ["sdds","dsads"]
var tempArray2: AnyObject = ["sddsa",34,tempArray1]
var dictionary: [String:Array] = ["key1":["value1"],"key2":["value2",6,tempArray2]]
The application crashed when I tried to print all values from the dictionary like
let allValues = [Array](dictionary.values)
for value in allValues{
println(value)
}
I just started learning dictionary concept in swift language. I want to know my approach is right or wrong.
Please help me to figure it out
As Swift arrays have associated I don't think that you can declare type with array without specifying its associated type. I am not sure why you do not get compile time errors. This should work:
var tempArray1 = ["sdds","dsads"]
var tempArray2: AnyObject = ["sddsa",34,tempArray1]
var dictionary: [String:Array<AnyObject>] = ["key1":["value1"],"key2":["value2",6,tempArray2]]
let allValues = [Array<AnyObject>](dictionary.values)
for value in allValues{
println(value)
}
Or even shorter:
var tempArray1 = ["sdds","dsads"]
var tempArray2: AnyObject = ["sddsa",34,tempArray1]
var dictionary: [String:[AnyObject]] = ["key1":["value1"],"key2":["value2",6,tempArray2]]
let allValues = dictionary.values
for value in allValues{
println(value)
}
You can try this also
var tempArray1 = ["sdds","dsads"]
var tempArray2: AnyObject = ["sddsa",34,tempArray1]
println("Array inside array \(tempArray2)")
var dictionary: [String:Array] = ["key1":["value1"],"key2":["value2",6,tempArray2]]
println(dictionary)
let allValues = Array(dictionary.values)
for value in allValues{
println(value)
}

Resources