Giter Site home page Giter Site logo

sh-khashimov / swiftfortunewheel Goto Github PK

View Code? Open in Web Editor NEW
334.0 8.0 81.0 38.65 MB

The ultimate spinning wheel view that supports dynamic content and rich customization.

License: MIT License

Swift 99.10% Ruby 0.90%
ios swift fortune fortune-wheel wheel spinning rotating lucky dynamic core-graphics

swiftfortunewheel's Introduction

SwiftFortuneWheel

CI Status Swift Version Version Support Platform Documentation

The ultimate spinning wheel control that supports dynamic content and rich customization.

Main Features
๐Ÿต Dynamic content, supports texts, images, and lines
๐ŸŽฏ Adaptive text size with support multiline, alignment and line break mode
๐ŸŽ‡ Supports background Image for each Slice (sector)
๐Ÿงฎ Supports vertical and horizontal text orientation
๐ŸŒˆ Appearance customization
๐Ÿ”Š Sounds and haptic feedback
๐ŸŒ‹ Collision callbacks and effects
๐ŸŽจ Drawn and animated using CoreGraphics, CoreAnimations
๐Ÿ”‹ High performance, low memory usage

Layout Preview

Taken from example projects

Dynamic Content and Rotation Preview

Taken from example projects

Collision Effect Preview

Taken from example projects

Screenshots

from iOS Example Project

from macOS Example Project

from tvOS Example Project

Documentation

Installation

When you are ready to install, follow the Installation Guide.

API Documentation

You can find the docs here.

Documentation is generated with jazzy and hosted on GitHub-Pages.

Requirements

App name Swift Xcode Platforms
1.1.4 - current version Swift 5.x Xcode 14 iOS 9.0 / macOS 10.13 / tvOS 9.0
1.1.x - 1.4.3 Swift 5.0 Xcode 11 iOS 9.0 / macOS 10.11 / tvOS 9.0
0.x.x - 1.0.x Swift 5.0 Xcode 11 iOS 9.0

Migration

Changelog

See changelog here

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

Author

Sherzod Khashimov

License

MIT

swiftfortunewheel's People

Contributors

johannesbauer97 avatar m-i-n avatar sh-khashimov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swiftfortunewheel's Issues

Rotation animation could be sometimes frozzen

This issue is repetible.
It could happen in case if SpinningWheelAnimator.addRotationAnimation() starts before the WheelView.addWheelLayer() has been finished. In this case layerToAnimate property of animationObject is nil, so the action animationObject?.layerToAnimate?.add(transformAnim, forKey:"starRotationAnim") did nothing and there will be no animation.

how to find the selected slice index

Hi

How can I find the the selected index in wheel so can change or highlight that slice if it have any. please help me out of that.

Thanks & Regard

Deepak

Delay when presenting new VC

There is a delay when presenting a new ViewController that contains the wheel, specifically when updateSlices() gets called. I tried calling updateSlices() in viewDidAppear and the wheel shows but the slices are not drawn yet. They appear after about 1 second.

Oscillating pin image when it collides with any of the separator

Can the pin image be oscillated?

Actually it should be like, the pin image rotates +ฮธ / -ฮธ degrees (depending on the direction of wheel rotation) and move back to original immediately after the collision imitating an oscillation effect.

I think a better visualisation would be these screenshots:
Screenshot 2020-07-07 at 12 18 02 AM
Screenshot 2020-07-07 at 12 22 04 AM

IB Designables issue

Error on console - Fail to render and update auto layout status for viewController(Tsg-HD-LBo): Failed to launch designable agent because tool was shutting down. check the console for a more detailed description and please file a bug report at feedbackassistant.com

on creating build the archive of app. work fine in debug mode. Please check this issue

Process: IBDesignablesAgent-iOS [49639]
Path: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Overlays/IBDesignablesAgent-iOS
Identifier: IBDesignablesAgent-iOS
Version: 12.3 (17703)
Code Type: X86-64 (Native)
Parent Process: launchd_sim [28516]
Responsible: SimulatorTrampoline [455]
User ID: 501

Date/Time: 2021-05-25 14:56:38.077 +0530
OS Version: macOS 11.1 (20C69)
Report Version: 12
Anonymous UUID: BFE8C29E-ACEE-3C30-748C-C5DF75B4B9C5

Time Awake Since Boot: 10000 seconds

System Integrity Protection: enabled

Crashed Thread: 0

Exception Type: EXC_BAD_INSTRUCTION (SIGILL)
Exception Codes: 0x0000000000000001, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY

Termination Signal: Illegal instruction: 4
Termination Reason: Namespace SIGNAL, Code 0x4
Terminating Process: exc handler [49639]

Application Specific Information:
CoreSimulator 757.5 - Device: iPhone 12 mini (1DD1CAF0-0420-4DAD-8DD0-5CDCE573BC9C) - Runtime: iOS 14.3 (18C61) - DeviceType: iPhone 12 mini
SwiftFortuneWheel/SwiftFortuneWheel.swift: 17: 14: Fatal error: Use of unimplemented initializer 'init(frame:)' for class 'SwiftFortuneWheel.SwiftFortuneWheel'

Can we shrink or scale the slice text? Some of slice Word is skipped

Hello, @sh-khashimov thanks for your awesome library.

I am using Podium Wheel Layout using variousWheelPodiumConfiguration

- What is the issue I am facing

  • In the slice, the text does not fully appear it's cropping somehow, I have also added an image for your reference

- What I have tried

  • I have set up the content margin & TextPreferences as well
          var wheelPreferences = SFWConfiguration.WheelPreferences(circlePreferences: circlePreferences,
                                                                 slicePreferences: slicePreferences,
                                                                 startPosition: .right)
        wheelPreferences.contentMargins = Margins(top: 0, left: 0, right: 0, bottom: 0)
       var preferences = TextPreferences(textColorType: textColorType,
                                         font: font,
                                         verticalOffset: 0)
       preferences.alignment = .left
       preferences.orientation = .vertical
       preferences.isCurved = false
       preferences.spacing = -1
       preferences.numberOfLines = 0
       public extension ImagePreferences {
          static var variousWheelPodiumImage: ImagePreferences {
             let imagePreferences = ImagePreferences(preferredSize: CGSize(width: 50, height: 50), verticalOffset: 0)
           return imagePreferences
         }
      }
  • I have decreased the font size but the large screen device shows a really small size of the font

- Questions โ“

  • Can we auto-shrink the font according to the device?
  • Do you have a temporary solution for it? If yes I will add it and also work on this project and I will create the PR
  • Could you please quickly suggest to me a file where I can review and temporarily fix my problem in the project?

Issue Reference:

Screenshot 2022-06-16 at 11 32 55 AM

External audio stops right after fortune wheel initialization

Navigating to a view controller that hosts a SwiftFortuneWheel stops any external audio that might have been being played within Music application.


Commenting the init() of AudioPlayerManager seems to fix this problem. But this might have other consequences somewhere else.

Note: I also need the collision sound effect to be enabled.

Support UIImage object alongside named image from asset

Firstly, thanks for this wonderful project.

Up until now, you have implemented it for the image to be set from the Assets.xcassets folder. I'm in a state where I need to be able to set image from external input (like, downloaded image or composed image with the help of UIGraphicsImageRenderer).

I think this should be a feature of your project which opens up possibilities for anyone in the future.

I've created #4 and awaiting for your consideration.

positioning on slice after update

Dear @sh-khashimov thanks for creating this library, its very useful.

I'm facing two issues right now can you please let me know how to solve them.

the first thing is that i need to text and position like that as image i did it with some hardcoding values so is there any better solution for that as you can see code its not look good.
Simulator Screen Shot - iPhone 11 - 2021-09-02 at 11 30 23

second issue is that im getting correct value as you mention in other solve issue the value after rotation, and pin is also correcting a correct value but now i have to update the color for the winning and losing slices for this i try to do add update slice function and checking condition, the issue is that color is updating for all but now position is shifting from the pin. like here the pin should point "Graphic" can you let me know what im doing wrong here.

Simulator Screen Shot - iPhone 11 - 2021-09-02 at 11 30 33

here is the code which im using right now:

`import UIKit
import SwiftFortuneWheel

class VariousWheelPodiumViewController: UIViewController {

var selectedIndex = -1


@IBOutlet weak var wheelControl: SwiftFortuneWheel!

var prizes = [(id:0,name: "MONEYMONEY", color: #colorLiteral(red: 0.9607843137, green: 0.768627451, blue: 0.568627451, alpha: 1),winningColor: #colorLiteral(red: 0.9333333333, green: 0.6078431373, blue: 0.2705882353, alpha: 1),losingColor: #colorLiteral(red: 0.737254902, green: 0.2901960784, blue: 0.6156862745, alpha: 1), textColor: #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)),
              (id:1,name: "GRAPHIC", color: #colorLiteral(red: 0.9843137255, green: 0.9098039216, blue: 0.8274509804, alpha: 1),winningColor: #colorLiteral(red: 0.9607843137, green: 0.768627451, blue: 0.568627451, alpha: 1), losingColor: #colorLiteral(red: 0.737254902, green: 0.2901960784, blue: 0.6156862745, alpha: 1),textColor: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)),
              (id:2,name: "HOME", color: #colorLiteral(red: 0.9607843137, green: 0.768627451, blue: 0.568627451, alpha: 1),winningColor: #colorLiteral(red: 0.9333333333, green: 0.6078431373, blue: 0.2705882353, alpha: 1),losingColor: #colorLiteral(red: 0.737254902, green: 0.2901960784, blue: 0.6156862745, alpha: 1), textColor: #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)),
              (id:3,name: "IDEA", color: #colorLiteral(red: 0.9843137255, green: 0.9098039216, blue: 0.8274509804, alpha: 1), winningColor: #colorLiteral(red: 0.9333333333, green: 0.6078431373, blue: 0.2705882353, alpha: 1), losingColor: #colorLiteral(red: 0.737254902, green: 0.2901960784, blue: 0.6156862745, alpha: 1),textColor: #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)),
              (id:4,name: "MANAGMENT", color: #colorLiteral(red: 0.9607843137, green: 0.768627451, blue: 0.568627451, alpha: 1),winningColor: #colorLiteral(red: 0.9333333333, green: 0.6078431373, blue: 0.2705882353, alpha: 1), losingColor: #colorLiteral(red: 0.737254902, green: 0.2901960784, blue: 0.6156862745, alpha: 1),textColor: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)),
              (id:5,name: "SEARCH", color: #colorLiteral(red: 0.9843137255, green: 0.9098039216, blue: 0.8274509804, alpha: 1),winningColor: #colorLiteral(red: 0.9333333333, green: 0.6078431373, blue: 0.2705882353, alpha: 1),  losingColor: #colorLiteral(red: 0.737254902, green: 0.2901960784, blue: 0.6156862745, alpha: 1),textColor: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)),
              (id:6,name: "TARGET", color: #colorLiteral(red: 0.9607843137, green: 0.768627451, blue: 0.568627451, alpha: 1),winningColor: #colorLiteral(red: 0.9333333333, green: 0.6078431373, blue: 0.2705882353, alpha: 1),  losingColor: #colorLiteral(red: 0.737254902, green: 0.2901960784, blue: 0.6156862745, alpha: 1),textColor: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)),
              (id:7,name: "TIME", color: #colorLiteral(red: 0.9843137255, green: 0.9098039216, blue: 0.8274509804, alpha: 1),winningColor: #colorLiteral(red: 0.9333333333, green: 0.6078431373, blue: 0.2705882353, alpha: 1), losingColor: #colorLiteral(red: 0.737254902, green: 0.2901960784, blue: 0.6156862745, alpha: 1),textColor: #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1))]



var slices = [Slice] ()

var finishIndex: Int {
    return Int.random(in: 0..<wheelControl.slices.count)
}



override func viewDidLoad() {
    super.viewDidLoad()

    wheelControl.configuration = .variousWheelPodiumConfiguration
    wheelControl.spinImage = "center"
    wheelControl.isSpinEnabled = false
    updateSlice()
    wheelControl.slices = slices
    
    
}

@IBAction func rotateTap(_ sender: Any) {
    let finishingIndex = self.finishIndex
    print(finishingIndex)
    wheelControl.startRotationAnimation(finishIndex: finishingIndex, continuousRotationTime: 1) { (isFinished) in
        guard isFinished else { return }
        print(self.prizes[finishingIndex])
        self.selectedIndex = finishingIndex
        self.updateSlice()
        self.wheelControl.slices = self.slices
        self.wheelControl.rotate(toIndex: finishingIndex)
    }
}

func updateSlice(){
    slices = []
    for (index,prize) in prizes.enumerated() {
        print(index,prize.name)
        
        var titleTextPreferences = TextPreferences(textColorType: .customPatternColors(colors: nil, defaultColor: .black), font: .systemFont(ofSize: 10, weight: .bold), verticalOffset: 20)
            titleTextPreferences.horizontalOffset = 10
            titleTextPreferences.orientation = .vertical
            titleTextPreferences.spacing = 0
            titleTextPreferences.alignment = .left
            
        var descriptionTextPreferences = TextPreferences(textColorType: .customPatternColors(colors: nil, defaultColor: .red), font: .systemFont(ofSize: 10), verticalOffset:-75)

        descriptionTextPreferences.horizontalOffset = 0
        descriptionTextPreferences.orientation = .vertical
        descriptionTextPreferences.spacing = 0
        descriptionTextPreferences.alignment = .left

        let content: [Slice.ContentType] = [.text(text: prize.name, preferences: titleTextPreferences),.text(text: prize.name, preferences: descriptionTextPreferences)]

        var slice = Slice(contents: content)
        if selectedIndex == -1{
            slice.backgroundColor = prize.color
        }else{
            slice.backgroundColor = index == selectedIndex ? prize.winningColor : prize.losingColor
        }
        slices.append(slice)
    }
   
}

}`

Rotate the slice image

Hello, Thanks!! for the Awsome project

@sh-khashimov I am using the Podium wheel with images so right now I want to rotate the image which is inside the slice
I have reviewed the ImageDrawing.swift and also played with

func drawImage(in context: CGContext, image: SFWImage, preferences: ImagePreferences, rotation: CGFloat, index: Int, topOffset: CGFloat, radius: CGFloat, margins: SFWConfiguration.Margins) {}

But no luck could you please help me what the best way to achieve the rotation of the image?

Thanks!

Cannot build on Xcode 14: Stored properties cannot be marked potentially unavailable with '@available'

Hi everyone, before working on a simple fix, just just wanted to check whether everyone is encountering this issue with Xcode 14?

Lines 128-131 of SwiftFortuneWheel.swift

#if os(iOS)
    @available(iOS 10.0, iOSApplicationExtension 10.0, *)
    private(set) lazy var impactFeedbackgenerator = UIImpactFeedbackGenerator(style: .light)
#endif

Error: Stored properties cannot be marked potentially unavailable with '@available'

Other librairies have encountered the same issue, the fix is not too difficult.
Could someone confirm they have the same issue? Thanks.

How to adjust indefinite spin speed

First, thank you so much for this project. I have been waiting for something like this for years!

Could you tell me what the best way is to adjust the initial speed of the wheel when it is in the indefinite spin mode?

Bridge UIViewControllerRepresentable SwiftUI

Is there currently any documentation on how to get the wheel implementation wrapped in an UIViewControllerRepresentable such that the package can be used in SwiftUI environments? I have tried to create a bridge myself and initializing a static wheel succeeded but did not manage to bridge the controls of the wheel. Thanks in advance!

startRotationAnimation completion issue

I don't understand why func startRotationAnimation(finishIndex: Int, continuousRotationTime: Int, continuousRotationSpeed: CGFloat = 4, _ completion: ((Bool) -> Void)?) is returning me always false and why the bool in completion it's returned before the wheel stops.

Slices are empty in class SwiftFortuneWheel

When using SwiftFortuneWheel without storyboard, startAnimating(finishIndex) vanishes with the wheel. I've did a little research and found out that slices are not assigned on to the SwiftFortuneWheel class, only to WheelView. When startAnimating(finishIndex) tries to calculate the sliceDegree, it tries to divide by zero, hence the bug.

I've fixed this in my code by reassigning to SwiftFortuneWheel slices variable

self.fortuneWheel = SwiftFortuneWheel(frame: frame, slices: mappedSlices, configuration: configuration)
self.fortuneWheel.slices = mappedSlices

But I think this can be easily be solved by assigning it at the init function of the SwiftFortuneWheel

SwiftFortuneWheelDemo-SwiftUI SFWConfiguration example not working

Changing the two examples to other implementations in the lib such as

@Published var wheelConfiguration: SFWConfiguration = .blackCyanColorsConfiguration
to
@Published var wheelConfiguration: SFWConfiguration = .variousWheelPodiumConfiguration

does not seem to work for me. A blank wheel is shown with the blackCyan layout.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.