Giter VIP home page Giter VIP logo

flashcard's Introduction

I'm Yusuf Kaan USTA

I am a person who enjoys developing iOS applications.

Screenshot 2023-06-14 at 20 44 15

Connect with me:

yusufkaanusta http://www.linkedin.com/in/%20%20yusuf-kaan-usta-998138252 @yusufkaanustaa https://dribbble.com/yusufkaan48 @yusufkaanusta

Languages and Tools:

c cplusplus csharp figma swift

flashcard's People

Watchers

 avatar

flashcard's Issues

Nice work! Some feedback.

Just some random feedback:

It turns out you don't need to call UserDefaults.synchronize anymore. See https://developer.apple.com/documentation/foundation/userdefaults/1414005-synchronize

Something I like to do when organizing my code is to follow something similar to the inverted pyramid from journalism: https://en.wikipedia.org/wiki/Inverted_pyramid_(journalism). In journalism, this means leading with the most important facts first, followed by supporting details, etc. For code, I interpret this as leading with the parts of the object which constitute the intended usage interface (the "public" part), followed by the internal implementation details.

e.g. instead of:

class MyFoo {
    public let a: Int
    private let b: Int
    public func doA() { }
    private func doB() {}
}

it might be something like:

class MyFoo {
    public let a: Int
    public func doA() { }

    // MARK: - Internals

    private let b: Int
    private func doB() {}
}

This way, folks who merely need to use your class only need to read the top part. People only need to read the bottom part if they are modifying your class.

I like the consistent use of style() and layout().

Consider extracting words and translations out of FlowLayout and TodayWordView. You'll probably want to drive these values from an API at some point in the future.

Don't be afraid to add lots of extensions to UIKit. e.g.

        NSLayoutConstraint.activate([
            backLabel.topAnchor.constraint(equalTo: backView.topAnchor),
            backLabel.bottomAnchor.constraint(equalTo: backView.bottomAnchor),
            backLabel.leadingAnchor.constraint(equalTo: backView.leadingAnchor),
            backLabel.trailingAnchor.constraint(equalTo: backView.trailingAnchor),
        ])

is very common and can be wrapped up as a function:

extension UIView {
    func pinToEdges(of otherView: UIView) {
        ...
    }
}

I don't see where isShowingBack is being reset on MyCell. Typically this would happen in prepareForReuse. I am surprised you aren't seeing cell re-use bugs with cards being recycled but being in the wrong flipped state?

FlowLayout is maybe not a good name for a view controller. Just based on the name, you'd expect this to be a subclass of UICollectionViewFlowLayout.

I find it useful to think of Swift code in terms of the "Value layer" vs. the "Object layer" (this concept was explored in a great talk by Andy Matuschak at https://academy.realm.io/posts/andy-matuschak-controlling-complexity/. Sadly, the video has been set to private, but the slides and transcript are still up).

When values are derived from other values, it can be useful to push them out of the object layer and into the value layer. This facilitates unit testing (no need to spin up a view controller), etc.

An example of doing this might be:

enum PeriodOfDay: Equatable {
    case morning
    case afternoon
    case evening
    
    static func from(hour: Int) -> Self {
        if hour >= 0 && hour < 12 {
            return .morning
        } else if hour >= 12 && hour < 18 {
            return .afternoon
        } else {
            return .evening
        }
    }
    
    var message: String {
        switch self {
        case .morning:
            return "Good Morning"
        case .afternoon:
            return "Good Afternoon"
        case .evening:
            return "Good Evening"
        }
    }
    
    var symbolName: String {
        switch self {
        case .morning:
            return "sun.max.fill"
        case .afternoon:
            return "cloud.sun.fill"
        case .evening:
            return "moon.stars.fill"
        }
    }
}

and then DailyMessageView.updateMessageAndIcon would become:

    private func updateMessageAndIcon() {
        let currentHour = Calendar.current.component(.hour, from: Date())
        let period = PeriodOfDay.from(hour: currentHour)
        messageLabel.text = period.message
        imageName = period.symbolName
    }

Where possible, try to avoid numeric constants when iterating over a collection.

Instead of:

        for i in 0..<5 {
            let index = savedWordIndices[i]
            if index < words.count {
                let word = words[index]
                let translation = translations[index]
                wordLabels[i].text = word
                translationLabels[i].text = translation
            } else {
                selectRandomWords()
                return
            }
        }

you can do:

        for (i, savedWordIndex) in savedWordIndices.enumerated() {
            if savedWordIndex < words.count {
                wordLabels[i].text = words[savedWordIndex]
                translationLabels[i].text = translations[savedWordIndex]
            } else {
                selectRandomWords()
                return
            }
        }

The weak classifier on MyHeaderClass.textLabel looks incorrect. MyHeaderClass "owns" this label, so it should be strongly retained. It happens to work because textLabel is retained as long as it stays in the view hierarchy, but this is what I would call a "landmine". When working on a team, at some point in the future someone may need to make a change which requires temporarily removing textLabel from the view hierarchy, which will cause it to deallocate and likely cause a crash. Then they are going to have to spend time hunting down the source of that bug.

Also, instead of making textLabel a force-unwrapped var, just make it a let:

let textLabel = UILabel()

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.