iCarousel numberOfItemsInCarousel - ios

I use iCarousel module into my CollectionView. The Carousel View is in my UICollectionViewCell.
My code is as following.
class CelebrityDetailHeaderCell: UICollectionViewCell, UITextFieldDelegate, SDCycleScrollViewDelegate, iCarouselDataSource, iCarouselDelegate {
#IBOutlet weak var backgroudLab: UILabel!
#IBOutlet weak var name_en: UILabel!
#IBOutlet weak var name_tw: UILabel!
#IBOutlet weak var intro: UILabel!
#IBOutlet weak var DetailImg: UIImageView!
#IBOutlet weak var iCarouselView: iCarousel!
let screenWidth = UIScreen.mainScreen().bounds.width
let screenHeight = UIScreen.mainScreen().bounds.height
override func awakeFromNib() {
super.awakeFromNib()
iCarouselView.delegate = self
iCarouselView.dataSource = self
iCarouselView.type = .Linear
}
func numberOfItemsInCarousel(carousel: iCarousel) -> Int {
return 1
}
func carousel(carousel: iCarousel, viewForItemAtIndex index: Int, reusingView view: UIView?) -> UIView {
let tempView = UIView(frame: CGRect(x: 0, y: screenWidth/2, width: screenWidth, height: screenWidth/2))
tempView.backgroundColor = UIColor.redColor()
return tempView
}
func carousel(carousel: iCarousel, valueForOption option: iCarouselOption, withDefault value: CGFloat) -> CGFloat {
if option == iCarouselOption.Spacing {
return 1.2
}
return value
}
}
The error message is as following
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSObject numberOfItemsInCarousel:]: unrecognized selector sent to instance 0x7f99bb3734a0'
I have set numberOfItemsInCarousel why the error message showed this. Does anyone help me? Thanks.

Look you need to add a dealloc method in your cell. As your cell is getting deallocated and the iCarousel delegate is calling that method to some deallocated instance thats why it is crashing
write a dealloc method like this
- (void)dealloc{
iCarouselView.delegate = nil
iCarouselView.dataSource = nil
}

Related

Unable to override scrollViewDidScroll from UIScrollViewDelegate

I am new to iOS and swift, I was trying to override scrollViewDidScroll() from UIScrollViewDelegate but it was showing me "Method does not override any method from its superclass" , I was following this tutorial https://www.youtube.com/watch?v=XQ3CVd8-zNE
This is the code I did.
class ViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var scrolliew: UIScrollView!
#IBOutlet weak var pageControl: UIPageControl!
var contentWidth:CGFloat=0.0
override func viewDidLoad() {
super.viewDidLoad()
scrolliew.delegate=self
for image in 0...3 {
let imageToDisplay = UIImage(named:"\(image).png")
let imageView = UIImageView(image:imageToDisplay)
scrolliew.addSubview(imageView)
let xCordinates = view.frame.minX + view.frame.width * CGFloat(image)
contentWidth += view.frame.width
imageView.frame=CGRect(x:xCordinates,y:view.frame.height/2,width:100,height:100)
}
scrolliew.contentSize=CGSize(width: contentWidth, height: view.frame.height)
}
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
//my code here
}
}
You don't actually have to override the method. scrollViewDidScroll(...) is part of the UIScrollViewDelegate protocol whose implementation is optional.
Just remove the override keyword in order to fix the error.

UIScrollView is being reset when editing UITextField

I'm new in Swift 3, and I just notice that we need to scroll a view since the keyboard can go over the some widgets as we type in text fields, like in this video. Fixing UITextField-Keyboard Problems (Swift in Xcode).
However, I am having an unfortunate behaviour even before programmatically scrolling the view. My view keeps being reset to its initial position. I made a video showing this behaviour.
I can't find mentions for this problem. Would someone have a clue?
[EDITED]
Here is the widgets are structured
Here is my View Controller code:
import UIKit
import AVFoundation
class SignUpController: UIViewController, UITextFieldDelegate
{
#IBOutlet var scrollView: UIScrollView!
#IBOutlet var stackView: UIStackView!
#IBOutlet var usernameTextField: UITextField!
#IBOutlet var passwordTextField: UITextField!
#IBOutlet var confirmationTextField: UITextField!
#IBOutlet var emailTextField: UITextField!
#IBOutlet var phoneTextField: UITextField!
#IBOutlet var firstNameTextField: UITextField!
#IBOutlet var lastNameTextField: UITextField!
#IBOutlet var signUpButton: UIButton!
var keyboardHeigh:CGFloat!
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.scrollView.contentSize = self.stackView.frame.size
self.scrollView.contentSize.height += self.stackView.frame.minY + 20
}
override func viewDidLoad() {
super.viewDidLoad()
let textFields :[UITextField] =
[
usernameTextField,
passwordTextField,
confirmationTextField,
emailTextField,
phoneTextField,
firstNameTextField,
lastNameTextField,
]
for i in 0..<textFields.count
{
textFields[i].delegate = self
textFields[i].tag = i
}
NotificationCenter.default.addObserver(self,
selector: #selector(keyboardWillShow),
name: .UIKeyboardWillShow, object: nil)
}
func keyboardWillShow(notification: NSNotification)
{
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue
{
keyboardHeigh = keyboardSize.height
}
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool
{
// Try to find next responder
if let nextField = textField.superview?.viewWithTag(textField.tag + 1) as? UITextField
{
nextField.becomeFirstResponder()
}
else
{
// Not found, so remove keyboard.
textField.resignFirstResponder()
}
return false
}
}
1.You can take UItableViewController with static cell,
2.Put textField inside cell.
3.Make selection for cell none.
4.Make separator none.
It will work fine.

Swift - label updates with SwiftRangeSlider

I am trying to work with SwiftRangeSlider implemented by BrianCorbin:
https://github.com/BrianCorbin/SwiftRangeSlider
#IBOutlet weak var labelForRangeSlider: UILabel!
#IBOutlet weak var rangeSlider: RangeSlider!
#IBOutlet weak var submitButton: UIButton!
override func viewDidLayoutSubviews() {
rangeSlider.updateLayerFrames()
}
...
And this shows:
I want to update "Time", which is labelForRangeSlider, as rangeSlider's lowerValue and upperValue change.
You are supposed to add action for the event .valueChanged for SwiftRangeSlider:
override func viewDidLoad() {
super.viewDidLoad()
let rangeSlider: RangeSlider = RangeSlider(frame: CGRect(x: 0, y: 0, width: 200, height: 60))
rangeSlider.addTarget(self, action: #selector(self.rangeSliderValueChanged(slider:)), for: UIControlEvents.valueChanged)
self.view.addSubview(rangeSlider)
}
#IBAction func rangeSliderValueChanged(slider: RangeSlider) {
print(slider.lowerValue)
}
Connect the IBAction below to the range slider in your storyboard and than you can change your label when you move the slider. You need to check lowerValue and upperValue of your slider.
#IBAction func rangeSliderValuesChanged(_ rangeSlider: slider) {
labelForRangeSlider.text "Min: \(slider.lowerValue), Max: (slider.upperValue)")
}

UIView doesn't center properly in UIScrollView with autolayout

I'm making an application where I need an x amount of custom UIView and place them in a scrollView. The layout of the scrollView and the UIView xib are set with AutoLayout. The result I'm getting now is this:
First View is well centred in ScrollView
Second View is wrong and has a lot of space in between
See my VC Code under here.
let sponsors = Sponsors.createSponsors() <-- Array
override func viewDidLoad() {
super.viewDidLoad()
configureSponsors()
}
//MARK: Load the AddView in ScrollView
func configureSponsors() {
self.scrollView.contentSize = CGSizeMake(CGFloat(sponsors.count) * self.scrollView.frame.size.width, self.scrollView.frame.size.height)
for sponsor in sponsors {
numberOfItems++
let addView = NSBundle.mainBundle().loadNibNamed("AddView", owner: self, options: nil).last as! AddView
addView.addDataToAddView(sponsor)
addView.frame = CGRectMake(CGFloat(numberOfItems - 1) * scrollView.frame.size.width, 0, scrollView.frame.size.width, scrollView.frame.size.height)
self.scrollView.addSubview(addView)
}
}
And here is my UIView code:
//MARK: Outlets
#IBOutlet weak var backgroundImageView: UIImageView!
#IBOutlet weak var sponsorTitle: UILabel!
#IBOutlet weak var sponsorLogo: UIImageView!
#IBOutlet weak var sponsorSubtitle: UILabel!
#IBOutlet weak var roundView: UIView!
#IBOutlet weak var playMusicButton: UIButton!
//MARK: Properties
var cornerRadius: CGFloat = 3.0
func addDataToAddView(sponsor: Sponsors) {
backgroundImageView.image = UIImage(named: sponsor.backgroundImage)
sponsorLogo.image = UIImage(named: sponsor.logoImage)
sponsorTitle.text = sponsor.title
sponsorSubtitle.text = sponsor.subTitle
}
override func layoutSubviews() {
roundView.layer.cornerRadius = roundView.frame.size.width / 2
roundView.alpha = 0.7
roundView.clipsToBounds = true
}
//MARK: PlayVideo
#IBAction func playVideo(sender: UIButton) {
//play music
}
I've already searched for the same problems. I found out that I have to use the Pure Auto Layout Approach. Should that mean I need to programatically set the constraints for the UIView?
Many thanks,
Dax
Update:
Pictures for scrollView setup:
You should not perform layout calculations in viewDidLoad as frames are not set correctly till then.
Correct place to do this is either viewWillLayoutSubviews or viewDidLayoutSubviews as you will get the correct frame data when these functions are called

Implementing Protocol in Swift to Change UIView's Attribute

I thought I wrote this correctly. I'm trying to get a value set in another viewcontroller (then stored in a singleton) to change the height of the rectangle in my BarGraphView, but my BarGraphView doesn't redraw when the value I'm passing in is changed...can anyone spot what I'm missing?
BarGraphViewController:
import UIKit
class BarGraphViewController: UIViewController, BarGraphViewDataSource {
#IBOutlet weak var barGraphView: BarGraphView! {
didSet {
barGraphView.datasource = self
}
}
#IBOutlet weak var testLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
var firstBarHeight: Int = 30 {
didSet {
firstBarHeight = SharkTankSingleton.instance.firstInvestorTotalasInt / 250
updateUI()
}
}
private func updateUI() {
barGraphView.setNeedsDisplay()
}
func firstBarHeightForBarGraphView(sender: BarGraphView) -> CGFloat? {
return CGFloat(firstBarHeight)
}
BarGraphView:
import UIKit
protocol BarGraphViewDataSource: class {
func firstBarHeightForBarGraphView(sender: BarGraphView) -> CGFloat?
}
#IBDesignable
class BarGraphView: UIView {
#IBInspectable var firstBarColor: UIColor = UIColor.blueColor()
weak var datasource: BarGraphViewDataSource?
override func drawRect(rect: CGRect) {
let firstBarHeight = datasource?.firstBarHeightForBarGraphView(self) ?? 0
let firstBar = CGRect(x: 200, y: 400, width: 30, height: firstBarHeight)
// firstBarColor.setFill()
var firstBarPath = UIBezierPath(rect: firstBar)
UIColor.redColor().setFill()
firstBarPath.fill()

Resources