I'm working on a swift project where I create a custom keyboard. In my ViewController, I store and mutate an array of UIImages. Then, in my Keyboard module in my keyboardViewcontroller.swift I would like to use the data I have in this array to create buttons. However, when I try to access the array in KeyBoardViewController it seems to give me an empty array and throws an index out of bounds error. What is strange to me is that in ViewController I print out the size of my array and it is definitely not empty. Here is how I'm storing the array:
import UIKit
class Main {
var pics :[UIImage]
init(pics : [UIImage]) {
self.pics = [UIImage]()
}
}
var instance = Main(pics: [UIImage]())
In ViewController I mutate it with instance.pics.append...
In my KeyboardViewController:
for image in instance.pics {
...
}
Why would this show as an empty array in KeyboardViewController?
Thanks
Rather than assigning an empty array of UIImage objects, the following will set the internal array variable to be a copy of the myPics array.
import UIKit
class Main {
var pics: [UIImage]
init(pics: [UIImage]) {
self.pics = pics
}
}
var instance = Main(pics: myPics)
Related
How should I handle a table view whose cells represent both a RLMResult and other custom views?
Say I have this structure, a todo list app that shows items of todo list and some ads:
protocol TableItem {}
class ToDoItem: RLMObject, TableItem {
// properties
}
class Advertising: TableItem {
// properties
}
class ViewController: UIViewController {
var result: RLMResult<ToDoItem>
var ads: [Advertising]
var tableViewItems: [TableItem] // Created by mixing both `result` and `ads`.
}
// other class stuff
I have to dequeue a different cell based on the the type of each item in tableViewItems.
The simplest thing would be to convert the result property to a simple Array<ToDoItem> and then concatenate both arrays; Realm documentation discourages to convert a RLMResult to a simple array to avoid losing all lazy features of RLMResult.
Any idea?
How do I keep the reference to an array after an items is appended?
Updated code example, because the prior example didn't seem to be clear enough.
class ViewController: UIViewController {
var numbers = Numbers.singleton.numbers
override func viewDidLoad() {
print(numbers.count)
Numbers.singleton.add(1)
print(numbers.count) // prints 0
print(Numbers.singleton.numbers.count) // prints 1
}
}
class Numbers {
static let singleton = Numbers()
var numbers: [Int]!
private init() {
numbers = []
}
func add(number: Int) {
numbers.append(number)
}
}
Arrays in Swift don't have "references". They are structs, and a struct is a value type. Your (badly named) arrayRef is a separate copy, not a reference to self.array.
Moreover, there is no good reason to want to do what you (seem to) want to do. To have two simultaneous references to a mutable array would be unsafe, since the array can be changed behind your back. The Swift design is sensible; use it, don't subvert it.
okay, i have an app with 3 view controllers and in 2 of them i have 5 arrays of images. what i want to do is save each array of images using realm. the arrays are mutable and the user adds the images to the array of their choosing in vc1 and can send them to the arrays in vc2, but im not sure if i can just replace (in vc1)
this:
var array: [UIImage] = [] {
didSet{
cView1.reloadData()
}
}
with This:
dynamic var array: [UIImage] = [] {
didSet{
cView1.reloadData()
}
}
i am also getting this error when i try to inherit RLMObject.
"multiple inheritance from classes uiviewcontroller and RLMObject"
here is my code
class CViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UICollectionViewDelegate, UICollectionViewDataSource, CDelegate , RLMObject
im fairly new to ios developing so any little bit helps thanks in advance
The best approach is to save file path in DB, not image itself. So you need to create array of image paths instead array of images. Like this: let images = List<String>()
Also according to Realm Docs 'List' can't be dynamic:
When added as a property on Object models, the property must be declared as let and cannot be dynamic.
And final, you must to inherit from 'Object', not 'RLMObject' and Realm class must be separate, like in this official example:
class Dog: Object {
dynamic var name: String = ""
dynamic var adopted: Bool = false
let siblings = List<Dog>()
}
This is my Realm object, basically an image with some tag attached.
class AllTags: Object {
dynamic var singleTag = ""}
class Photo: Object {
var myTags: [String] {
get {
return _backingNewTags.map { $0.singleTag }
}
set {
_backingNewTags.removeAll()
_backingNewTags.appendContentsOf(newValue.map({ AllTags(value: [$0]) }))
}
}
let _backingNewTags = List<AllTags>()
override static func ignoredProperties() -> [String] {
return ["myTags"]
}
dynamic var imagePath = ""}
I have my collectionView, I can see all my photo and when pressing an image I can see my tags, so everything is working correctly.
I have added my UISearchBar, added the txtSearchbar.delegate = self and using let data = realm.objects(AllTags).map { $0.singleTag } I can print ALL the tags inside my database.
I just need to filter in real time while I type the CollectionView cells via the UISearchBar so it shows only the images tagged with the word I'm typing. Basic.
I've been following this tutorial to filter in the collectionView - https://github.com/codepath/ios_guides/wiki/Search-Bar-Guide#example-searching-a-collection-view - After 11 hours, I can't figure out how to make it works with Realm. With hardcoded Array like the example I can make it works.
In Realm, you can filter a Results<T> based on what you're looking for. For example:
let data = realm.objects(AllTags).filter("singleTag CONTAINS %#", searchTerm)
I'm wondering, however, why you're converting your _backingNewTags to an Array [String]? Why can't you just access the tags directly? This will be much more memory & CPU efficient, and will simplify your code...
I have a superclass UIViewController that contains this:
var results: [AnyObject] = []
I also have other methods in the superclass that's based on the content of results array.
I then have subclasses that inherit from this superclass, by loading data from REST API to populate results array with various types of data.
I currently don't override results array in subclass' viewDidLoad() or any other method. I simply clear the array using results = [] and then load the array with a specific class type, such as a custom class Product or String.
results.append(Product())
I've been intermittenly getting crashes, but I can't tell why. I suspect it's due to the way the inheritance is working. Am I doing this correctly? Should I be overriding results in an init() method of the subclass or using `override var?
I think typecasting can work here.
Try to do this in your subclasses:
class SubClass: SuperClass {
private var _results: [Product] = []
override var results: [AnyObject] {
get {
return _results
}
set {
_results = newValue as! [Product]
}
}
}
But Product must be a class and not struct or enum.
Also as String does not conform to AnyObject you cannot save Strings in results array.