如何在 swift 项目中使用 TPKeyboardAvoiding?

Posted

技术标签:

【中文标题】如何在 swift 项目中使用 TPKeyboardAvoiding?【英文标题】:How to use TPKeyboardAvoiding in swift project? 【发布时间】:2016-02-25 11:03:31 【问题描述】:

我在我的 Objective c 应用程序中使用了 TPKeyboardAvoiding 滚动视图。 现在我想在我的 swift 项目中使用它。 我已经搜索过,但我没有得到确切的步骤。

感谢帮助

【问题讨论】:

使用桥接头.... 【参考方案1】:

Swift 4.1, 只需在情节提要或 xib 中为您的滚动视图分配相应的类。

// MARK: - TableView
class TPKeyboardAvoidingTableView:UITableView,UITextFieldDelegate, UITextViewDelegate 

    override var frame:CGRect
        willSet
            super.frame = frame
        

        didSet
            if hasAutomaticKeyboardAvoidingBehaviour() return
            TPKeyboardAvoiding_updateContentInset()
        
    

    override var contentSize:CGSize
        willSet(newValue)
            if hasAutomaticKeyboardAvoidingBehaviour() 
                super.contentSize = newValue
                return
            

            if newValue.equalTo(self.contentSize)
            
                return
            

            super.contentSize = newValue
            self.TPKeyboardAvoiding_updateContentInset()
        

        //        didSet
        //            self.TPKeyboardAvoiding_updateContentInset()
        //        
    


    override init(frame: CGRect, style: UITableViewStyle) 
        super.init(frame: frame, style: style)
        self.setup()
    

    required init?(coder aDecoder: NSCoder) 
        super.init(coder: aDecoder)
        self.setup()
    

    override func awakeFromNib() 
        setup()
    

    deinit
        NotificationCenter.default.removeObserver(self)
    

    func hasAutomaticKeyboardAvoidingBehaviour()->Bool
    
        if #available(ios 8.3, *) 
            if self.delegate is UITableViewController
            
                return true
            
        

        return false
    

    func focusNextTextField()->Bool
    
        return self.TPKeyboardAvoiding_focusNextTextField()
    

    @objc func scrollToActiveTextField()
    
        return self.TPKeyboardAvoiding_scrollToActiveTextField()
    

    override func willMove(toSuperview newSuperview: UIView?) 
        super.willMove(toSuperview: newSuperview)
        if newSuperview != nil 
            NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), object: self)
        
    

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) 
        self.TPKeyboardAvoiding_findFirstResponderBeneathView(self)?.resignFirstResponder()
        super.touchesEnded(touches, with: event)
    

    func textFieldShouldReturn(_ textField: UITextField) -> Bool 
        if !self.focusNextTextField()
        
            textField.resignFirstResponder()
        
        return true
    

    override func layoutSubviews() 
        super.layoutSubviews()
        NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), object: self)

        Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), userInfo: nil, repeats: false)
    


private extension TPKeyboardAvoidingTableView

    func setup()
    
        if self.hasAutomaticKeyboardAvoidingBehaviour()  return 

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(TPKeyboardAvoiding_keyboardWillShow(_:)),
                                               name: NSNotification.Name.UIKeyboardWillChangeFrame,
                                               object: nil)

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(TPKeyboardAvoiding_keyboardWillHide(_:)),
                                               name: NSNotification.Name.UIKeyboardWillHide,
                                               object: nil)

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(scrollToActiveTextField),
                                               name: NSNotification.Name.UITextViewTextDidBeginEditing,
                                               object: nil)

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(scrollToActiveTextField),
                                               name: NSNotification.Name.UITextFieldTextDidBeginEditing,
                                               object: nil)
    


// MARK: - CollectionView
class TPKeyboardAvoidingCollectionView:UICollectionView,UITextViewDelegate 

    override var contentSize:CGSize
        willSet(newValue)
            if newValue.equalTo(self.contentSize)
            
                return
            

            super.contentSize = newValue
            self.TPKeyboardAvoiding_updateContentInset()
        

    


    override var frame:CGRect
        willSet
            super.frame = frame
        

        didSet
            self.TPKeyboardAvoiding_updateContentInset()
        
    

    //    override init(frame: CGRect) 
    //        super.init(frame: frame)
    //    

    override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) 
        super.init(frame: frame, collectionViewLayout: layout)
        setup()
    

    required init?(coder aDecoder: NSCoder) 
        //        fatalError("init(coder:) has not been implemented")
        super.init(coder: aDecoder)
        self.setup()

    

    override func awakeFromNib() 
        setup()
    

    deinit
        NotificationCenter.default.removeObserver(self)
    

    func focusNextTextField()->Bool
    
        return self.TPKeyboardAvoiding_focusNextTextField()
    

    @objc func scrollToActiveTextField()
    
        return self.TPKeyboardAvoiding_scrollToActiveTextField()
    

    override func willMove(toSuperview newSuperview: UIView?) 
        super.willMove(toSuperview: newSuperview)
        if newSuperview != nil 
            NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), object: self)
        
    

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) 
        self.TPKeyboardAvoiding_findFirstResponderBeneathView(self)?.resignFirstResponder()
        super.touchesEnded(touches, with: event)
    

    func textFieldShouldReturn(_ textField: UITextField) -> Bool 
        if !self.focusNextTextField()
        
            textField.resignFirstResponder()
        
        return true
    

    override func layoutSubviews() 
        super.layoutSubviews()
        NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), object: self)

        Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), userInfo: nil, repeats: false)
    


private extension TPKeyboardAvoidingCollectionView

    func setup()
    
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(TPKeyboardAvoiding_keyboardWillShow(_:)),
                                               name: NSNotification.Name.UIKeyboardWillChangeFrame,
                                               object: nil)

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(TPKeyboardAvoiding_keyboardWillHide(_:)),
                                               name: NSNotification.Name.UIKeyboardWillHide,
                                               object: nil)

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(scrollToActiveTextField),
                                               name: NSNotification.Name.UITextViewTextDidBeginEditing,
                                               object: nil)

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(scrollToActiveTextField),
                                               name: NSNotification.Name.UITextFieldTextDidBeginEditing,
                                               object: nil)
    


// MARK: - ScrollView
class TPKeyboardAvoidingScrollView:UIScrollView,UITextFieldDelegate,UITextViewDelegate

    override var contentSize:CGSize
        didSet
            self.TPKeyboardAvoiding_updateFromContentSizeChange()
        
    


    override var frame:CGRect
        didSet
            self.TPKeyboardAvoiding_updateContentInset()
        
    

    override init(frame: CGRect) 
        super.init(frame: frame)
        self.setup()
    

    override func awakeFromNib() 
        setup()
    

    func contentSizeToFit()
    
        self.contentSize = self.TPKeyboardAvoiding_calculatedContentSizeFromSubviewFrames()
    

    func focusNextTextField() ->Bool
    
        return self.TPKeyboardAvoiding_focusNextTextField()
    

    @objc func scrollToActiveTextField()
    
        return self.TPKeyboardAvoiding_scrollToActiveTextField()
    

    required init?(coder aDecoder: NSCoder) 
        super.init(coder: aDecoder)
        self.setup()
    

    deinit
        NotificationCenter.default.removeObserver(self)
    

    override func willMove(toSuperview newSuperview: UIView?) 
        super.willMove(toSuperview: newSuperview)
        if newSuperview != nil 
            NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), object: self)
        
    

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) 
        self.TPKeyboardAvoiding_findFirstResponderBeneathView(self)?.resignFirstResponder()
        super.touchesEnded(touches, with: event)
    

    func textFieldShouldReturn(_ textField: UITextField) -> Bool 
        if !self.focusNextTextField()
        
            textField.resignFirstResponder()
        
        return true
    

    override func layoutSubviews() 
        super.layoutSubviews()
        NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), object: self)

        Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), userInfo: nil, repeats: false)
    


private extension TPKeyboardAvoidingScrollView

    func setup()
    
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(TPKeyboardAvoiding_keyboardWillShow(_:)),
                                               name: NSNotification.Name.UIKeyboardWillChangeFrame,
                                               object: nil)

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(TPKeyboardAvoiding_keyboardWillHide(_:)),
                                               name: NSNotification.Name.UIKeyboardWillHide,
                                               object: nil)

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(scrollToActiveTextField),
                                               name: NSNotification.Name.UITextViewTextDidBeginEditing,
                                               object: nil)

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(scrollToActiveTextField),
                                               name: NSNotification.Name.UITextFieldTextDidBeginEditing,
                                               object: nil)
    


// MARK: - Process Event
let kCalculatedContentPadding:CGFloat = 10;
let kMinimumScrollOffsetPadding:CGFloat = 20;

extension UIScrollView

    @objc func TPKeyboardAvoiding_keyboardWillShow(_ notification:Notification)
    
        guard let userInfo = notification.userInfo else  return 
        guard let rectNotification = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue else
        
            return
        

        let keyboardRect = self.convert(rectNotification.cgRectValue , from: nil)
        if keyboardRect.isEmpty
        
            return
        

        let state = self.keyboardAvoidingState()

        guard let firstResponder = self.TPKeyboardAvoiding_findFirstResponderBeneathView(self) else  return
        state.keyboardRect = keyboardRect
        if !state.keyboardVisible
        
            state.priorInset = self.contentInset
            state.priorScrollIndicatorInsets = self.scrollIndicatorInsets
            state.priorPagingEnabled = self.isPagingEnabled
        

        state.keyboardVisible = true
        self.isPagingEnabled = false

        if self is TPKeyboardAvoidingScrollView
        
            state.priorContentSize = self.contentSize
            if self.contentSize.equalTo(CGSize.zero)
            
                self.contentSize = self.TPKeyboardAvoiding_calculatedContentSizeFromSubviewFrames()
            
        

        let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? Float ?? 0.0
        let curve = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? Int ?? 0
        let options = UIViewAnimationOptions(rawValue: UInt(curve))

        UIView.animate(withDuration: TimeInterval(duration),
                       delay: 0,
                       options: options,
                       animations:  [weak self]() -> Void in
                        if let actualSelf = self
                        
                            actualSelf.contentInset = actualSelf.TPKeyboardAvoiding_contentInsetForKeyboard()
                            let viewableHeight = actualSelf.bounds.size.height - actualSelf.contentInset.top - actualSelf.contentInset.bottom
                            let point = CGPoint(x: actualSelf.contentOffset.x, y: actualSelf.TPKeyboardAvoiding_idealOffsetForView(firstResponder, viewAreaHeight: viewableHeight))
                            actualSelf.setContentOffset(point, animated: false)

                            actualSelf.scrollIndicatorInsets = actualSelf.contentInset
                            actualSelf.layoutIfNeeded()
                        

        )  (finished) -> Void in

        
    

    @objc func TPKeyboardAvoiding_keyboardWillHide(_ notification:Notification)
    
        guard let userInfo = notification.userInfo else  return 

        guard let rectNotification = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue else
        
            return
        
        let keyboardRect = self.convert(rectNotification.cgRectValue , from: nil)
        if keyboardRect.isEmpty
        
            return
        
        let state = self.keyboardAvoidingState()

        if !state.keyboardVisible
        
            return
        
        state.keyboardRect = CGRect.zero
        state.keyboardVisible = false

        let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? Float ?? 0.0
        let curve = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? Int ?? 0
        let options = UIViewAnimationOptions(rawValue: UInt(curve))

        UIView.animate(withDuration: TimeInterval(duration),
                       delay: 0,
                       options: options,
                       animations:  [weak self]() -> Void in
                        if let actualSelf = self
                        
                            if actualSelf is TPKeyboardAvoidingScrollView 
                                actualSelf.contentSize = state.priorContentSize
                                actualSelf.contentInset = state.priorInset
                                actualSelf.scrollIndicatorInsets = state.priorScrollIndicatorInsets
                                actualSelf.isPagingEnabled = state.priorPagingEnabled
                                actualSelf.layoutIfNeeded()
                            
                        

        )  (finished) -> Void in

        
    

    func TPKeyboardAvoiding_updateFromContentSizeChange()
    
        let state = self.keyboardAvoidingState()
        if state.keyboardVisible
        
            state.priorContentSize = self.contentSize
        
    

    func TPKeyboardAvoiding_focusNextTextField() ->Bool
    
        guard let firstResponder = self.TPKeyboardAvoiding_findFirstResponderBeneathView(self) else  return false
        guard let view = self.TPKeyboardAvoiding_findNextInputViewAfterView(firstResponder, beneathView: self) else  return false
        Timer.scheduledTimer(timeInterval: 0.1, target: view, selector: #selector(becomeFirstResponder), userInfo: nil, repeats: false)

        return true

    

    func TPKeyboardAvoiding_scrollToActiveTextField()
    
        let state = self.keyboardAvoidingState()

        if !state.keyboardVisible  return 

        let visibleSpace = self.bounds.size.height - self.contentInset.top - self.contentInset.bottom

        let idealOffset = CGPoint(x: 0,
                                  y: self.TPKeyboardAvoiding_idealOffsetForView(self.TPKeyboardAvoiding_findFirstResponderBeneathView(self),
                                                                                viewAreaHeight: visibleSpace))

        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double((Int64)(0 * NSEC_PER_SEC)) / Double(NSEC_PER_SEC)) [weak self] () -> Void in
            self?.setContentOffset(idealOffset, animated: true)
        
    

    //Helper
    func TPKeyboardAvoiding_findFirstResponderBeneathView(_ view:UIView) -> UIView?
    
        for childView in view.subviews
        
            if childView.responds(to: #selector(getter: isFirstResponder)) && childView.isFirstResponder
            
                return childView
            
            let result = TPKeyboardAvoiding_findFirstResponderBeneathView(childView)
            if result != nil
            
                return result
            
        
        return nil
    

    func TPKeyboardAvoiding_updateContentInset()
    
        let state = self.keyboardAvoidingState()
        if state.keyboardVisible
        
            self.contentInset = self.TPKeyboardAvoiding_contentInsetForKeyboard()
        
    

    func TPKeyboardAvoiding_calculatedContentSizeFromSubviewFrames() ->CGSize
    
        let wasShowingVerticalScrollIndicator = self.showsVerticalScrollIndicator
        let wasShowingHorizontalScrollIndicator = self.showsHorizontalScrollIndicator

        self.showsVerticalScrollIndicator = false
        self.showsHorizontalScrollIndicator = false

        var rect = CGRect.zero

        for view in self.subviews
        
            rect = rect.union(view.frame)
        

        rect.size.height += kCalculatedContentPadding
        self.showsVerticalScrollIndicator = wasShowingVerticalScrollIndicator
        self.showsHorizontalScrollIndicator = wasShowingHorizontalScrollIndicator

        return rect.size
    

    func TPKeyboardAvoiding_idealOffsetForView(_ view:UIView?,viewAreaHeight:CGFloat) -> CGFloat
    
        let contentSize = self.contentSize

        var offset:CGFloat = 0.0
        let subviewRect =  view != nil ? view!.convert(view!.bounds, to: self) : CGRect.zero

        var padding = (viewAreaHeight - subviewRect.height)/2
        if padding < kMinimumScrollOffsetPadding
        
            padding = kMinimumScrollOffsetPadding
        

        offset = subviewRect.origin.y - padding - self.contentInset.top

        if offset > (contentSize.height - viewAreaHeight)
        
            offset = contentSize.height - viewAreaHeight
        

        if offset < -self.contentInset.top
        
            offset = -self.contentInset.top
        

        return offset
    

    func TPKeyboardAvoiding_contentInsetForKeyboard() -> UIEdgeInsets
    
        let state = self.keyboardAvoidingState()
        var newInset = self.contentInset;

        let keyboardRect = state.keyboardRect
        newInset.bottom = keyboardRect.size.height - max(keyboardRect.maxY - self.bounds.maxY, 0)

        return newInset

    

    func TPKeyboardAvoiding_viewIsValidKeyViewCandidate(_ view:UIView)->Bool
    
        if view.isHidden || !view.isUserInteractionEnabled return false

        if view is UITextField
        
            if (view as! UITextField).isEnabled return true
        

        if view is UITextView
        
            if (view as! UITextView).isEditable return true
        

        return false
    

    func TPKeyboardAvoiding_findNextInputViewAfterView(_ priorView:UIView,beneathView view:UIView, candidateView bestCandidate: inout UIView?)
    
        let priorFrame = self.convert(priorView.frame, to: priorView.superview)
        let candidateFrame = bestCandidate == nil ? CGRect.zero : self.convert(bestCandidate!.frame, to: bestCandidate!.superview)

        var bestCandidateHeuristic = -sqrt(candidateFrame.origin.x*candidateFrame.origin.x + candidateFrame.origin.y*candidateFrame.origin.y) + ( Float(fabs(candidateFrame.minY - priorFrame.minY))<Float.ulpOfOne ? 1e6 : 0)

        for childView in view.subviews
        
            if TPKeyboardAvoiding_viewIsValidKeyViewCandidate(childView)
            
                let frame = self.convert(childView.frame, to: view)
                let heuristic = -sqrt(frame.origin.x*frame.origin.x + frame.origin.y*frame.origin.y)
                    + (Float(fabs(frame.minY - priorFrame.minY)) < Float.ulpOfOne ? 1e6 : 0)

                if childView != priorView && (Float(fabs(frame.minY - priorFrame.minY)) < Float.ulpOfOne
                    && frame.minX > priorFrame.minX
                    || frame.minY > priorFrame.minY)
                    && (bestCandidate == nil || heuristic > bestCandidateHeuristic)
                
                    bestCandidate = childView
                    bestCandidateHeuristic = heuristic
                
            else
            
                self.TPKeyboardAvoiding_findNextInputViewAfterView(priorView, beneathView: view, candidateView: &bestCandidate)
            
        
    

    func TPKeyboardAvoiding_findNextInputViewAfterView(_ priorView:UIView,beneathView view:UIView) ->UIView?
    
        var candidate:UIView?
        self.TPKeyboardAvoiding_findNextInputViewAfterView(priorView, beneathView: view, candidateView: &candidate)
        return candidate
    


    @objc func TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_ obj: AnyObject)
    
        func processWithView(_ view: UIView) 
            for childView in view.subviews
            
                if childView is UITextField || childView is UITextView
                
                    self.TPKeyboardAvoiding_initializeView(childView)
                else
                
                    self.TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(childView)
                
            
        

        if let timer = obj as? Timer, let view = timer.userInfo as? UIView 
            processWithView(view)
        
        else if let view = obj as? UIView 
            processWithView(view)
        
    

    func TPKeyboardAvoiding_initializeView(_ view:UIView)
    
        if let textField = view as? UITextField,
            let delegate = self as? UITextFieldDelegate, textField.returnKeyType == UIReturnKeyType.default &&
            textField.delegate !== delegate
        
            textField.delegate = delegate
            let otherView = self.TPKeyboardAvoiding_findNextInputViewAfterView(view, beneathView: self)
            textField.returnKeyType = otherView != nil ? .next : .done

        
    

    func keyboardAvoidingState()->TPKeyboardAvoidingState
    
        var state = objc_getAssociatedObject(self, &AssociatedKeysKeyboard.DescriptiveName) as? TPKeyboardAvoidingState
        if state == nil
        
            state = TPKeyboardAvoidingState()
            self.state = state
        

        return self.state!
    



// MARK: - Internal object observer
internal class TPKeyboardAvoidingState:NSObject

    var priorInset = UIEdgeInsets.zero
    var priorScrollIndicatorInsets = UIEdgeInsets.zero

    var keyboardVisible = false
    var keyboardRect = CGRect.zero
    var priorContentSize = CGSize.zero

    var priorPagingEnabled = false


internal extension UIScrollView

    fileprivate struct AssociatedKeysKeyboard 
        static var DescriptiveName = "KeyBoard_DescriptiveName"
    

    var state:TPKeyboardAvoidingState?
        get
            let optionalObject:AnyObject? = objc_getAssociatedObject(self, &AssociatedKeysKeyboard.DescriptiveName) as AnyObject?
            if let object:AnyObject = optionalObject 
                return object as? TPKeyboardAvoidingState
             else 
                return nil
            
        
        set
            objc_setAssociatedObject(self, &AssociatedKeysKeyboard.DescriptiveName, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        
    

【讨论】:

相应的意思是,滚动视图、表格视图或集合视图,无论您使用的是哪个。【参考方案2】:

将文件添加到您的项目中,而不是为每个 .h 文件添加一个桥接头。然后您可以使用 Storyboard 将自定义类更改为相关类。

【讨论】:

【参考方案3】:

要运行示例项目,请克隆存储库,然后首先从示例目录运行 pod install。 安装 TPKeyboardAvoidingSwift 可通过 CocoaPods 获得。要安装它,只需将以下行添加到您的 Podfile 中: pod "TPKeyboardAvoidingSwift" 给 TPKeyboardAvoiding 滚动视图。 https://github.com/apple-avadhesh/TPKeyboardAvoiding

【讨论】:

我认为给定的代码会更新到 swift 3.0。所以我对 Swift 4.1 中的代码编译做了一些小改动,答案贴在下面【参考方案4】:

您可以像在 Obj-C 应用程序中一样使用它。

首先将 pod 'TPKeyboardAvoiding' 添加到您的 Podfile。

然后只需将 TPKeyboardAvoiding 导入 .swift 文件。

示例用法:

    private var scrollView: TPKeyboardAvoidingScrollView!
    (...)
    self.scrollView = TPKeyboardAvoidingScrollView()

行为将与 Obj-C 应用程序中的行为相同

【讨论】:

以上是关于如何在 swift 项目中使用 TPKeyboardAvoiding?的主要内容,如果未能解决你的问题,请参考以下文章

Swift - 如何对 ScrollView 中的项目使用自动布局?

如何在目标 c-swift 桥接项目中使用 intentdefinition 文件?

如何在 Swift 2 中使用 TableView 项目访问视图控制器?

如何使用 Swift 在我的项目中使用内部 JSON?

如何手动将第三方Swift框架导入Swift iOS项目?

如何在 Swift 项目中管理文件夹? [复制]