Simple question, but I don't get the answer of satisfaction.
So, I want to add some constraints to my added UIViewController via code.
Thank you so much :)
override func viewDidLoad() {
let imageLogoName = "pictureIsInAssets"
let imageLogo = UIImage(named: imageLogoName)
let imageLogoView = UIImageView(image: imageLogo!)
setImageContraints()
}
func setImageContraints(){
imageLogoView.translatesAutoresizingMaskIntoConstraints = false
imageLogoView.widthAnchor.constraint(equalToConstant: 180).isActive = true
imageLogoView.heightAnchor.constraint(equalToConstant: 180).isActive = true
imageLogoView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
imageLogoView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 28).isActive = true
}
In the func setImageContraints:
Error: Use of unresolved identifier 'imageLogoView'
You are using variable imageLogoView outside of it's visibility/life cycle scope. You should have an instance variable instead:
class SomeViewController {
var imageLogoView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad() // <-- notice this
let imageLogoName = "pictureIsInAssets"
let imageLogo = UIImage(named: imageLogoName)
self.imageLogoView = UIImageView(image: imageLogo!)
setImageContraints()
}
}
or simpler:
class SomeViewController {
let imageLogoView = UIImageView(image: UIImage(imageLiteralResourceName: "pictureIsInAssets"))
override func viewDidLoad() {
super.viewDidLoad() // <-- notice this
setImageContraints()
}
}
And don't forget to add the image view to the view.
imageLogoView is no global variable.
You have to declare it like that:
class ViewController: UIViewController{
let imageLogoView: UIImageView!
override func viewDidLoad() {
let imageLogoName = "pictureIsInAssets"
let imageLogo = UIImage(named: imageLogoName)
imageLogoView = UIImageView(image: imageLogo!)
setImageContraints()
}
}
Related
SOLUTION FOUND - credit Sanzio Angeli, used lazy var
Trying the access the pageIndex in order to update the page indicator , i try and create an instance of a class which has the public property of pageIndex, but the moment i try and do so its crashing the app, can any on one please suggest where i am doing wrong, Strange enough if i do not declare the instance globally but inside a method, the app does not crash
Error i get - Thread 1: EXC_BAD_ACCESS (code=2, address=0x7ffeeebccea8)
Below is class whose instance i am trying to create and after that the class where i am trying to call it by creating a global instance at top, i am trying to use it in func moveToNext()
import UIKit
class ContentViewController: UIViewController {
let contentDesign = ContentView()
var pageIndex = 0
var pageHeading = ""
var pageContent = ""
var pageImage = ""
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(contentDesign)
contentDesign.pagerContent.text = pageContent
contentDesign.pagerHeader.text = pageHeading
contentDesign.pagerImage.image = UIImage(named: pageImage)
// Do any additional setup after loading the view.
}
}
//////---------
class MasterView: UIViewController {
var container = UIView()
var lowerCotainer = UIView()
var pageNumbering: UIPageControl = UIPageControl()
var nextButton = UIButton()
var skipButton = UIButton()
var pageController = PageViewController()
**var content = ContentViewController()**
override func viewDidLoad() {
super.viewDidLoad()
commonInit()
}
func commonInit()
{
container.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(container)
container.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width).isActive = true
container.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.height * 0.6).isActive = true
}
#objc func moveToNext() {
// let index = pageController.currentIndex
let index = content.pageIndex
pageNumbering.currentPage = index + 1
print(index)
switch index {
case 0...1:
pageController.forwardPage()
case 2:
self.view.window?.rootViewController?.dismiss(animated: true, completion: nil)
default:
break
}
}
}
Where the app crashes is strange here in another class at var pagerHeader = UILabel()
import UIKit
class ContentView: UIView {
var pagerImage = UIImageView()
var pagerHeader = UILabel()
var pagerContent = UILabel()
let master = MasterView()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func commonInit()
{
pagerImage.translatesAutoresizingMaskIntoConstraints = false
addSubview(pagerImage)
}
}
After working with multiverse:
lazy var content = ContentViewController()
Instead of:
var content = ContentViewController()
Has fixed the issue
I am trying to access a variable from a different class. What am I doing wrong?
class ViewController: UIViewController {
var restaurantName = "Test"
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func btnClicked(_ sender: Any) {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()){
let pop = popView()
self.view.addSubview(pop)
}
}
}
here is the class I am trying to access it from:
class popView: UIView{
fileprivate let titleLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.systemFont(ofSize:28, weight: .bold)
label.textAlignment = .center
//label.text = "TITLE"
label.text = restaurantName
return label
}()
}
How can I access the 'restaurantName' variable in the 'popView' class?
thanks in advance
You don't want to tightly couple the view and the view controller.
You should have a property on your PopView to hold the text. You can then assign a value to this property when you create the PopView instance.
class PopView: UIView{
fileprivate let titleLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.systemFont(ofSize:28, weight: .bold)
label.textAlignment = .center
//label.text = "TITLE"
label.text = restaurantName
return label
}()
var titleText: String? {
didSet {
self.titleLabel.text = titleText
}
}
}
class ViewController: UIViewController {
var restaurantName = "Test"
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func btnClicked(_ sender: Any) {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()){
let pop = popView()
pop.titleText = restaurantName
self.view.addSubview(pop)
}
}
}
You simply cant access 'restaurantName' variable in the 'popView' class since the "popupView" class is an instance of "ViewController".
If you want to assign property "restaurantName" to "titleLabel" simply remove the "fileprivate" from property "titleLabel" and add this line before the "addSubview" func.
pop.titleLabel.text = restaurantName
also change your "popView" class to the following
class popView: UIView{
weak var titleLabel: UILabel!
func awakeFromNib() {
super.awakeFromNib()
titleLabel = UILabel()
titleLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.font = UIFont.systemFont(ofSize:28, weight: .bold)
titleLabel.textAlignment = .center
}
I have a viewcontroller that has a tableview and a button at the bottom. Within each cell is a radio button as a tapGesture. I would like to updated the button with the number of cells selected. If my gesture is in the custom cell and my button is in my viewcontroller how can I get the two to work together?
Custom cell:
class SearchTalentCell: UITableViewCell {
#IBOutlet weak var userProfileImage: UIImageView!
#IBOutlet weak var talentUserName: UILabel!
#IBOutlet weak var selectedImg: UIImageView!
#IBOutlet weak var inviteSentImg: UIImageView!
var prospectRef: FIRDatabaseReference!
var currentTalent: UserType!
func setTalent(talent: UserType) {
currentTalent = talent
currentTalent.userKey = talent.userKey
}
override func awakeFromNib() {
super.awakeFromNib()
let tap = UITapGestureRecognizer(target: self, action: #selector(selectTapped))
tap.numberOfTapsRequired = 1
selectedImg.addGestureRecognizer(tap)
selectedImg.isUserInteractionEnabled = true
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func configureCell(user: UserType, img: UIImage? = nil) {
prospectRef = Cast.REF_PRE_PRODUCTION_CASTING_POSITION.child(ProjectDetailVC.currentProject).child(FIRDataCast.prospect.rawValue).child(CastingDetailVC.positionName).child(user.userKey)
setTalent(talent: user)
self.talentUserName.text = "\(user.firstName) \(user.lastName)"
prospectRef.observeSingleEvent(of: .value, with: { (snapshot) in
if let _ = snapshot.value as? NSNull {
self.inviteSentImg.isHidden = true
} else {
self.inviteSentImg.image = UIImage(named: "inviteSent")
self.inviteSentImg.isHidden = false
}
})
if UserType.selectedTalentForSearch.contains(currentTalent.userKey) {
selectedImg.image = UIImage(named: "radioSelected")
} else {
selectedImg.image = UIImage(named: "radioUnselected")
}
//Image Caching
if img != nil {
self.userProfileImage.image = img
} else {
if let imageURL = user.profileImage {
let ref = FIRStorage.storage().reference(forURL: imageURL)
ref.data(withMaxSize: 2 * 1024 * 1024, completion: { (data, error) in
if error != nil {
print("ZACK: Unable to download image from Firebase Storage")
} else {
print("ZACK: Image downloaded from Firebase Storage")
if let imgData = data {
if let img = UIImage(data: imgData) {
self.userProfileImage.image = img
SearchTalentVC.userProfileImageCache.setObject(img, forKey: imageURL as NSString)
}
}
}
})
}
}
}
#objc func selectTapped(sender: UITapGestureRecognizer) {
if UserType.selectedTalentForSearch.contains(currentTalent.userKey) {
selectedImg.image = UIImage(named: "radioUnselected")
UserType.selectedTalentForSearch = UserType.selectedTalentForSearch.filter{$0 != currentTalent.userKey}
print("Keys: \(UserType.selectedTalentForSearch)")
} else {
selectedImg.image = UIImage(named: "radioSelected")
UserType.selectedTalentForSearch.append(currentTalent.userKey)
print("Keys: \(UserType.selectedTalentForSearch)")
}
}
}
ViewController:
class SearchTalentVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var sendInviteButton: UIButton!
var searchingRole = [Cast]()
var unfilteredTalent = [UserType]()
var filteredTalent = [UserType]()
var selectedTalent = [UserType]()
var matchingTalentUserKeys = [String]()
var isFiltered = false
var selectedCounter = [String]()
var prospectRef: FIRDatabaseReference!
static var userProfileImageCache: NSCache<NSString, UIImage> = NSCache()
let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Search Talent"
searchController.searchBar.barStyle = .black
navigationItem.searchController = searchController
definesPresentationContext = true
searchController.searchBar.scopeButtonTitles = ["All", "Role Specific"]
searchController.searchBar.tintColor = UIColor.white
searchController.searchBar.delegate = self
searchController.searchResultsUpdater = self
self.sendInviteButton.setTitle("Send Invite to \(UserType.selectedTalentForSearch.count) Prospects", for: .normal)
getTalentProfiles()
}
Thank you for any help!
I'm not sure why you are using the cell selection inside the cell, as opposed to the tableview delegate function func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)?
If you use didSelectRowAt, you could have an array of selected rows and you can include the selectedRows.count into your button text.
Hope that helps!
I can change background image on viewDidLoad func like this:
let myBackgroundImage = UIImageView (frame: UIScreen.main.bounds)
myBackgroundImage.image = UIImage(named: "wallpaper-1-iphone-8-plus.png")
myBackgroundImage.contentMode = UIViewContentMode.scaleAspectFill
self.view.insertSubview(myBackgroundImage, at: 0)
i would like to do same action with button click like this:
#IBAction func flip4btn5(_ sender: Any)
{
let myBackgroundImage = UIImageView (frame: UIScreen.main.bounds)
myBackgroundImage.image = UIImage(named: "wallpaper-2-iphone-8-plus.png")
myBackgroundImage.contentMode = UIViewContentMode.scaleAspectFill
self.view.insertSubview(myBackgroundImage, at: 0)
}
but it does not change background image. Why ? What do you think ?
I'm using Swift 4.1.
Don't create a new image. just change the picture of the first UIImage in your button action like this:
myBackgroundImage.image = UIImage(named: "wallpaper-2-iphone-8-plus.png")
Try this code, It's working fine.
class ViewController: UIViewController {
var myBackgroundImage = UIImageView (frame: UIScreen.main.bounds);
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
myBackgroundImage.image = UIImage(named: "wallpaper-1-iphone-8-plus.png")
myBackgroundImage.contentMode = UIViewContentMode.scaleAspectFill
self.view.insertSubview(myBackgroundImage, at: 0)
}
#IBAction func flip4btn5(_ sender: UIButton) {
myBackgroundImage.image = UIImage(named: "wallpaper-2-iphone-8-plus.png")
}
}
Don't keep adding UIImageViews everytime you want to change the background image.
Place a UIImageView in the view hierarchy where it is needed and keep a reference to it. Then set the image property on it as needed.
class ViewController: UIViewController {
#IBOutlet weak var backgroundImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
backgroundImageView.image = UIImage(named: "wallpaper-1-iphone-8-plus.png")
}
#IBAction func flip4btn5(_ sender: Any) {
backgroundImageView.image = UIImage(named: "wallpaper-2-iphone-8-plus.png")
}
}
You can set the contentMode either in the storyboard or in viewDidLoad. You don't need to keep setting it after updating an image.
let myBackgroundImage = UIImageView (frame: CGRect.zero)
override func viewDidLoad() {
super.viewDidLoad()
myBackgroundImage.image = UIImage(named: "wallpaper-1-iphone-8-plus.png")
myBackgroundImage.contentMode = UIViewContentMode.scaleAspectFill
self.view.addSubview(myBackgroundImage)
}
#IBAction func ButtonPressed(_ sender: Any) {
myBackgroundImage.image = UIImage(named: "wallpaper-2-iphone-8-plus.png")
}
I'm trying to update a UIimageview image with a method inside a class with a viewDidLoad() call. I'm trying to change the image by:
MyIMage.image = UIImage(named: "image2")
but its giving me the error of:
Instance member cannot be used on type "view controller"
Where am I going wrong?
My Code:
import UIKit
class ViewController: UIViewController {
#IBOutlet var MyImage: UIImageView!
var MyStruct = ChangeImage()
struct ChangeImage {
private var _isChanged: Bool = false
mutating func Set_Change(val: Bool) {
if (val) {
MyImage.image = UIImage(named: "image2")
self._isChanged = true
} else {
MyImage.image = UIImage(named: "image1")
self.isChanged = false
}
}
func isChanged()-> Bool {
return self._isChanged
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
MyStruct.Set_Change(val: true)
print (MyStruct.isChanged())
}
}
Here is the extract of the code corrected but with the same error in line : let _myImage = MyImage()
class ViewController: UIViewController {
#IBOutlet var MyImage: UIImageView!
var MyStruct = ChangeImage()
struct ChangeImage {
private var _isChanged: Bool = false
let _myImage = MyImage() // ----> Error : Instance member ‘MyImage’ cannot be used on type ‘ViewController’
mutating func Set_Change(val: Bool) {
if (val) {
_myImage.image = UIImage(named: "image2")
self._isChanged = true
} else {
_myImage.image = UIImage(named: "image1")
self._isChanged = false
}
}
func isChanged()-> Bool {
return self._isChanged
}
}
I think your problem is that the structure can't use the variable from the ViewController class, so I changed it to a function that does the same thing:
import UIKit
class ViewController: UIViewController {
#IBOutlet var myImage: UIImageView!
func Set_Change(val: Bool) -> Bool {
if (val) {
myImage.image = UIImage(named: "image2")
return true
} else {
myImage.image = UIImage(named: "image1")
return false
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let didChange = Set_Change(val: true)
print(didChange)
}
}
Here's the solution that works :
import UIKit
class ViewController: UIViewController {
#IBOutlet var MyImage: UIImageView! // Insert Outlet Image : "MyImage"
// Structure ChangeImage
struct ChangeImage {
private var _isChanged: Bool = false
private var _myImage: UIImageView! // Private variable _myImage
init (ImgView: UIImageView) { // Initiate ImgView called since func viewDidLoad()
self._myImage = ImgView // Private variable _myImage = ImgView ( variable MyImage in func viewDidLoad() )
}
mutating func Set_Change(val: Bool) {
if (val) {
_myImage.image = UIImage(named: "image2")
self._isChanged = true
} else {
_myImage.image = UIImage(named: "image1")
self._isChanged = false
}
}
func isChanged()-> Bool {
return self._isChanged
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var MyStruct = ChangeImage(ImgView: MyImage) // Initiate Structure ChangeImage with variable MyImage.
MyStruct.Set_Change(val: true)
print (MyStruct.isChanged())
}
}
;)