I'm creating an iOS app with Swift and am using iCarousel from GitHub (installed via cocoapods) and I'm not sure what I'm doing wrong, but I can't seem to get iCarouselOptions I set to have any effect...
What I want to do is simply change the spacing of the UIViews in my carousel (They are too close together and overlapping, which I don't want).
Here is my code:
import UIKit
import iCarousel
class MiniGamesViewController: UIViewController, iCarouselDelegate, iCarouselDataSource {
//Objects
#IBOutlet weak var leaveMinigamesButton: UIButton!
//Variables
var carouselHeight : CGFloat!
var selectionBallSize : CGFloat!
override func viewDidLoad() {
super.viewDidLoad()
leaveMinigamesButton.layer.zPosition = 3
carouselHeight = self.view.frame.size.height - 200
selectionBallSize = self.view.frame.size.width * 0.65
let carousel = iCarousel(frame: CGRect(
x: 0,
y: 100,
width: self.view.frame.size.width,
height: carouselHeight))
carousel.perspective = -0.005
carousel.centerItemWhenSelected = true
carousel.decelerationRate = 0.9
carousel.viewpointOffset = CGSize(width: 0, height: 0) //-selectionBallSize * 1.2
carousel.dataSource = self
carousel.type = .rotary
view.addSubview(carousel)
}
override func viewDidAppear(_ animated: Bool) {
setNeedsStatusBarAppearanceUpdate()
}
//This is how many items there will be in my rotary iCarousel
func numberOfItems(in carousel: iCarousel) -> Int {
return 6
}
//This defines each item or 'cell' in the iCarousel
func carousel(_ carousel: iCarousel, viewForItemAt index: Int, reusing view: UIView?) -> UIView {
let imageView: UIImageView
if view != nil {
imageView = view as! UIImageView
} else {
imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: selectionBallSize, height: selectionBallSize))
}
imageView.image = UIImage(named: "orbCyan")
return imageView
}
func carousel(_ carousel: iCarousel, valueFor option: iCarouselOption, withDefault value: CGFloat) -> CGFloat {
switch (option) {
case .spacing: return value * 2
case .radius: return 200
case .fadeMinAlpha: return 0.5
default: return value
}
}
}
Specifically the very bottom of my code is where the customization
is supposed to take effect, but it doesn't seem to be making any changes when I run the app. At the moment, I'm only concerned with trying to space the UIViews in the carousel to be further apart.
Am I putting the iCarouselOptions function in the right place? Is it even being 'called' at all?
Thanks for your help!
Wouldn't you know it, as soon as I posted this question I found the issue haha (after a day of trying everything). Turns out I was missing the simple line:
carousel.delegate = self
underneath:
carousel.dataSource = self
That totally did the trick and it works now lol. I need a fresh set of eyes :P
Related
I have an UIViewController where there is an UIScrollView, there also is a function (build()) to draw UIView's in the UIScrollView.
Problem : Nothing appears in the UIViewController, but when I scroll (so when I update the UIScrollView) the UIView's, I wanted, appear.
I tried setNeedsDisplay() to force the redrawing but it doesn't work...
A video to help you to understand the problem :
https://vimeo.com/user87689481/review/281597574/3cccb78dc1
Here is the code of the UIViewController:
import UIKit
class MainViewController: UIViewController {
#IBOutlet weak var body: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
navigationController?.navigationBar.prefersLargeTitles = true
navigationController?.navigationItem.largeTitleDisplayMode = .always
DispatchQueue.global(qos: .background).async {
while !Home.accessories.isInitialized {}
DispatchQueue.main.async {
self.build(Home.accessories.toUIView())
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
public func build(_ s: [UISectionView]) {
let topMargin = 10
let rightMargin = 10
let leftMargin = 10
let space = 5
let heightItem = 60
var b = topMargin
for t in s {
if t.isHidden == true {
continue
}
if t.title != nil {
let f = UIFont(name: "Helvetica", size: 20)
let l = UILabel(frame: CGRect(x: rightMargin, y : b, width: Int(UIScreen.main.bounds.width) - (rightMargin + leftMargin), height: Int(f!.lineHeight)))
l.font = f
l.text = t.title
body.addSubview(l)
b = b + Int(f!.lineHeight) + space
}
for i in t.items {
body.addSubview(i.getView(frame: CGRect(x: rightMargin, y: b, width: Int(UIScreen.main.bounds.width) - (rightMargin + leftMargin), height: heightItem), view: self))
b = b + heightItem + space
}
}
body.contentSize = CGSize(width: UIScreen.main.bounds.width, height: CGFloat(b))
//a code to force body (UIScrollView) to refresh/relaod/redraw/update/...
}
}
I hope we can help me =D
Thanks in advance !
There is no method to redraw a UIScrollView, then only thing you need to do is:
Add views to UIScrollView
Set contentSize of the UIScrollView so that it allows user to pan around and see all of the contents of the UIScrollView
What you are doing in your code seems ok, because you are doing both of the things listed above.
Problem is either if your ts are hidden:
if t.isHidden == true {
continue
}
Or you are calling build() method somewhere else on the Background thread
To be sure you are not doing that you can just add assert(Thread.isMainThread, "Never call me on background thread") as the first line in build() method
Here is a ViewController that creates 4 subviews using init(repeating:count).
In viewDidLoad I add them as subviews and set their frames. When I run the application only the last view is added.
class ViewController: UIViewController {
let subviews = [UIView].init(repeating: UIView(), count: 4)
override func viewDidLoad() {
super.viewDidLoad()
for i in 0..<subviews.count {
self.view.addSubview(subviews[i])
self.subviews[i].backgroundColor = UIColor.red
self.subviews[i].frame = CGRect(x: CGFloat(i) * 35, y: 30, width: 30, height: 30)
}
}
}
Here's the same code except instead of using init(repeating:count) I use
a closure. This works fine-- all subviews are added.
class ViewController: UIViewController {
let subviews: [UIView] = {
var subviews = [UIView]()
for i in 0..<4 {
subviews.append(UIView())
}
return subviews
}()
override func viewDidLoad() {
//same as above...
}
}
You’ve put the same instance of UIView in your array four times. Your viewDidLoad just ends up moving that single view around. You need to create four separate instances of UIView.
let subviews = (0 ..< 4).map({ _ in UIView() })
I have VPMOTPView custom view in my `.xib' like this.
class VerifyOTP: UIView {
#IBOutlet weak var otpView: VPMOTPView!
var emailID = ""
var userID = ""
#IBAction func resendOTPAction(_ sender: UIButton) {
print("asdds")
}
override func awakeFromNib() {
super.awakeFromNib()
otpView.otpFieldsCount = 4
otpView.otpFieldDefaultBorderColor = UIColor.blue
otpView.otpFieldEnteredBorderColor = UIColor.red
otpView.otpFieldBorderWidth = 2
otpView.delegate = self
// Create the UI
otpView.initalizeUI()
}
}
extension VerifyOTP: VPMOTPViewDelegate {
func hasEnteredAllOTP(hasEntered: Bool) {
print("Has entered all OTP? \(hasEntered)")
}
func enteredOTP(otpString: String) {
print("OTPString: \(otpString)")
}
}
Then in my 'ViewController'
var verifyOTPView: VerifyOTP?
self.verifyOTPView = VerifyOTP.fromNib()
self.verifyOTPView?.frame = CGRect(x: 20, y: 0, width: screenSize.width - 40, height: screenSize.height / 3)
self.view.addSubview(self.verifyOTPView!)
But by this I can see my RESEND OTP button on screen but OTPVIEW is not displayed.
From the screenshot it doesn't look like you have any constraints set up for your views?
If not try adding constraints and see if that fixes the problem.
I have an array of strings, and I want to set them up, so the user can scroll through the strings, and which ever one it lands on that one is selected, but I am unsure on how to do it. I was thinking of using a scroll view or a pagevc, but those take up the whole view, and it will show one string per page. Instead I need them side by side so I can see the value one ahead or one behind. A roadmap on how to execute this would be perfect, I am so lost on this component.
func numberOfItemsInCarousel(carousel: iCarousel) -> Int {
//getInfo()
return animal.count
}
func carousel(carousel: iCarousel, viewForItemAtIndex index: Int, reusingView view: UIView?) -> UIView {
var labelsubject: UILabel
var itemView: UIImageView
var labelname: UILabel
var cardimage: UIImageView
var cardtypeimage: UIImageView
if(view == nil){
itemView = UIImageView(frame:CGRect(x:0, y:0, width:400, height:100))
itemView.image = UIImage(named: "page")
itemView.contentMode = .Center
labelsubject = UILabel(frame: itemView.bounds)
labelsubject.backgroundColor = UIColor.clearColor()
labelsubject.textAlignment = .Center
labelsubject.textColor = UIColor.whiteColor()
labelsubject.tag = 1
itemView.addSubview(labelsubject)
}else{
itemView = view as! UIImageView;
labelsubject = itemView.viewWithTag(1) as! UILabel!
}
selectedData.anim = animal[index]
return itemView
}
func carouselDidEndDragging(carousel: iCarousel, willDecelerate decelerate: Bool) {
if !decelerate {
print(carousel.currentItemIndex)
//text[carousel.currentItemIndex]
}
}
func carouselDidEndDecelerating(carousel: iCarousel) {
print(carousel.currentItemIndex)
//text[carousel.currentItemIndex]
}
There is a Main View with subview. I need to get these subviews.
For example, I created a view:
With the Swift Code:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
// Check if has view in rect area
let rect1 = CGRect(x: 0, y: 0, width: 100, height: 100)
if CGRectContainsPoint(rect1, rect1.origin) { // return true
print("TRUE")
} else {
print("FALSE")
}
}
}
I need to get the view you are "touching" the Rect in size or origin.
In the above example, I created three subviews with different colors between them.
I need to get the view and make a print() with the backgroundColor.
Can someone help me?
This func fix the problem:
func intersectingViewWithView(panView: UIView) -> UIView? {
for view in self.view.subviews {
if view != panView {
if CGRectIntersectsRect(panView.frame, view.frame) {
return view
}
}
}
return nil
}