Skip to content

Instantly share code, notes, and snippets.

View dterekhov's full-sized avatar

Dmitry Terekhov dterekhov

  • Russia, Voronezh
View GitHub Profile
@dterekhov
dterekhov / URLOpeningUtil.swift
Created November 13, 2025 09:21
URLOpeningUtil: Correctly opens phone, email URLs in the app #uikit #swift-api #real-project
import UIKit
import MessageUI
public final class URLOpeningUtil: NSObject, Sendable {
// MARK: - Validation
public enum RegularExpressions: String {
// swiftlint:disable line_length
case phone = "^\\s*(?:\\+?(\\d{1,3}))?([-. (]*(\\d{3})[-. )]*)?((\\d{3})[-. ]*(\\d{2,4})(?:[-.x ]*(\\d+))?)\\s*$"
case email = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
// swiftlint:enable line_length
@dterekhov
dterekhov / InvalidFieldDetector.swift
Created November 13, 2025 09:19
InvalidFieldDetector: Detects what the field is invalid/empty, scrolls to it and shakes #uikit #swift-api #real-project
import Foundation
import UIKit
public class InvalidFieldDetector {
public static func isNumeric(string: String) -> Bool {
let nums: Set<Character> = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
return Set(string).isSubset(of: nums)
}
public static func isValidEmail(email: String) -> Bool {
@dterekhov
dterekhov / UIViewController+Embed.swift
Created November 13, 2025 09:17
UIViewController+Embed: Embeds a newly created view controller of the given type into a container view #uikit #swift-api #real-project
import UIKit
extension UIViewController {
/// Embeds a newly created view controller of the given type into a container view.
/// - Parameters:
/// - vcType: The type of the view controller to embed.
/// - containerView: The container view that will hold the embedded view.
/// - setup: Optional configuration closure executed after the view is added.
public func fw_initEmbedVC(ofType vcType: UIViewController.Type,
inside containerView: UIView,
@dterekhov
dterekhov / UIView+Border.swift
Created November 13, 2025 09:16
UIView+Border: Access to the UIView’s border to mange its width, color, type #uikit #swift-api #real-project
import UIKit
@IBDesignable extension UIView {
@IBInspectable var borderColor: UIColor? {
set { layer.borderColor = newValue?.cgColor }
get { return layer.borderColor == nil ? nil : UIColor(cgColor: layer.borderColor!) }
}
}
extension UIView {
@dterekhov
dterekhov / UITableViewCell+UITableViewAccess.swift
Created November 13, 2025 09:14
UITableViewCell+UITableViewAccess: An easy access to the parent UITableView from its UITableViewCell #uikit #swift-api #real-project
import UIKit
extension UITableViewCell {
/// Search up the view hierarchy of the table view cell to find the containing table view
public var fw_tableView: UITableView? {
var table: UIView? = superview
while !(table is UITableView) && table != nil {
table = table?.superview
}
return table as? UITableView
@dterekhov
dterekhov / UITableViewCell+ClearButton.swift
Created November 13, 2025 09:13
UITableViewCell+ClearButton: Adds clear data button to the cell #uikit #swift-api #real-project
import UIKit
extension UITableViewCell {
// MARK: - Public API
public var fw_onClearButtonTap: (() -> Void)? {
get { return objc_getAssociatedObject(self, AssociatedKeys.onClearButtonTap) as? () -> Void }
set {
objc_setAssociatedObject(self,
AssociatedKeys.onClearButtonTap,
newValue,
@dterekhov
dterekhov / UITableView+EmptyData.swift
Created November 13, 2025 09:09
UITableView+EmptyData: Placehoder for UITableView on no data state #uikit #swift-api #real-project
import UIKit
extension UITableView {
// MARK: - Public API
public func fw_setPlaceholder
(text: String?,
fontSize: CGFloat = 21,
image: UIImage?,
edgeInsets: UIEdgeInsets = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8)) {
let stackView = fw_placeholderStackView()
@dterekhov
dterekhov / String+PercentEncodingFormatting.swift
Created November 13, 2025 09:08
String+PercentEncodingFormatting: Format a string in a way to use correctly for URLQueryItem #utility #swift-api #real-project
import Foundation
extension String {
// Encoding for x-www-form-urlencoded
// https://useyourloaf.com/blog/how-to-percent-encode-a-url-string/
public func addingPercentEncodingForFormData(plusForSpace: Bool = true) -> String? {
let unreserved = "*-._,"
var allowed = CharacterSet.alphanumerics
allowed.insert(charactersIn: unreserved)
if plusForSpace { allowed.insert(charactersIn: " ") }
@dterekhov
dterekhov / PaddingLabel.swift
Created November 13, 2025 09:05
PaddingLabel: Simple adding insest for UILabel #uikit #swift-api #real-project
import UIKit
@IBDesignable public class PaddingLabel: UILabel {
// MARK: - Members
@IBInspectable public var topInset: CGFloat = 0.0
@IBInspectable public var bottomInset: CGFloat = 0.0
@IBInspectable public var leftInset: CGFloat = 0.0
@IBInspectable public var rightInset: CGFloat = 0.0
// MARK: - Lifecycle
@dterekhov
dterekhov / KeyedCodingContainer+UIImage.swift
Created November 13, 2025 09:04
KeyedCodingContainer+UIImage: UImage support for KeyedEncodingContainer #uikit #persistence #swift-api #real-project
import UIKit.UIImage
public enum ImageEncodingQuality: CGFloat {
case png = 0
case jpegLow = 0.2
case jpegMid = 0.5
case jpegHigh = 0.75
}
public extension KeyedEncodingContainer {