Задать вопрос
  • Как можно определить кнопку в SWIFT3?

    doublench21
    @doublench21 Куратор тега Swift
    Для этого в методе
    @IBAction func buttonPressed(_ sender: UIButton) { ... }
    есть аргумент sender по которому Вы и можете различать какая именно кнопка вызвала этот action. А вообще бы лучше основную свою задачу описали, а то так не очень понятно что Вы хотите. Зачем Вам findById( findByClass ) ? Для этого есть IBOutlets. Если Вы ищите кнопку среди subviews, то тут можно приводить каждый subview к типу UIButton(если это возможно) и смотреть скажем его title или смотреть его RestorationID.
    Ответ написан
    Комментировать
  • Почему не происходит transition у UISearchController`а?

    doublench21
    @doublench21 Автор вопроса, куратор тега Swift
    Вообщем, разобрался. Это никакой ни UISearchController, а обычный UISearchBar c кастомным аниматором UIViewPropertyAnimator.
    Ответ написан
    2 комментария
  • Как исправить ошибку с autolayout?

    doublench21
    @doublench21 Куратор тега Swift
    Ну так вместо width, лучше ставьте left right по нулям и уберите центр
    Ответ написан
  • Как сделать collectionView в tableView?

    doublench21
    @doublench21 Куратор тега Swift
    Не понял Вас. Ну есть у вас tableviewcell.xib и сопутствующий ему условный UITableViewCell.swift. В нём находится UICollectionView. Теперь делаете IBOutlet UICollectionView в файле UITableViewCell.swift. Ну и есть у вас также collectionviewcell.xib и сопутствующий ему условный UICollectionViewCell.swift. И допустим один контроллер UIViewController.swift. У вас очевидно есть доступ и к UITableView и UICollectionView. Теперь достаточно в этом контроллере указать его самого в качестве делегата для обеих коллекций. Вот и всё.

    UITableView есть уже как IBOutlet в вашем контроллере.
    А IBOutlet UICollectionView есть в классе UITableViewCell.

    Поправьте, если что не понял.
    Ответ написан
    1 комментарий
  • На чем лучше делать серверную часть для мобильного приложения на iOS (SWIFT) и Android (Java)?

    doublench21
    @doublench21 Куратор тега Swift
    Серверная часть и iOS. Повеселили. Какое отношение к серверной части имеет iOS, мб просто Swift, эмм? А если по делу, то наверное серверную часть не пишут ни на одном из этих языков. Java - забыть как страшный сон(ИМХО). Swift тема крутая, + на Линкусе без проблем крутится, но он пока молод. На сервер его ещё рано. Не вся основная библиотека(Foundation) переделана от привязки к obj-c runtime. Пишите на том, на чём пишут все: NodeJS, Php, Ruby, Python.
    Ответ написан
  • Как сделать выезжающее из-под uitextfield оповещение?

    doublench21
    @doublench21 Куратор тега Swift
    Ну наверно как-то так, хотя за правильность я не ручаюсь.
    import UIKit
    
    class ViewController: UIViewController {
        @IBOutlet weak var textField: UITextField!
        private var substrateView = UIView()
        private var substrateLabel = UILabel()
        private var constraint = NSLayoutConstraint()
    
        @IBAction func someAction(_ sender: Any) {
            substrateView.isHidden = false
            UIView.animate(withDuration: 0.3) { [unowned self] in
                self.constraint.isActive = false
                self.constraint = self.substrateView.heightAnchor.constraint(equalToConstant: 60)
                self.constraint.isActive = true
                self.view.layoutIfNeeded()
            }
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            textField.layer.borderWidth = 3
            textField.layer.borderColor = UIColor(red: 233/255, green: 128/255, blue: 129/255, alpha: 1).cgColor
            textField.layer.cornerRadius = 8
    
            substrateView.backgroundColor = UIColor(red: 233/255, green: 128/255, blue: 129/255, alpha: 1)
            substrateView.layer.cornerRadius = 8
    
            substrateLabel.text = "Login is not valid"
            substrateLabel.textAlignment = .center
            substrateLabel.textColor = UIColor.white
            substrateLabel.backgroundColor = UIColor.clear
    
            substrateView.addSubview(substrateLabel)
    
            substrateLabel.translatesAutoresizingMaskIntoConstraints = false
            substrateLabel.frame = CGRect.zero
            substrateLabel.sizeToFit()
            substrateLabel.bottomAnchor.constraint(equalTo: substrateView.bottomAnchor).isActive = true
            substrateLabel.centerXAnchor.constraint(equalTo: substrateView.centerXAnchor).isActive = true
    
            view.addSubview(substrateView)
    
            substrateView.translatesAutoresizingMaskIntoConstraints = false
            substrateView.topAnchor.constraint(equalTo: textField.topAnchor).isActive = true
            substrateView.leftAnchor.constraint(equalTo: textField.leftAnchor).isActive = true
            substrateView.rightAnchor.constraint(equalTo: textField.rightAnchor).isActive = true
            substrateView.widthAnchor.constraint(equalTo:textField.widthAnchor).isActive = true
    
            constraint = substrateView.heightAnchor.constraint(equalTo: textField.heightAnchor)
            constraint.isActive = true
    
            textField.layer.zPosition = 1
            substrateView.isHidden = true
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
    
    }


    Вышло как-то так:
    giphy.gif
    Конечно сам action выберешь такой какой тебе нужен. На гифке - вызывается просто по нажатию.
    Ответ написан
    5 комментариев
  • Как сделать тень в uitextfield разную с двух сторон?

    doublench21
    @doublench21 Куратор тега Swift
    Достаточно просто. Нужно делать через свойство UIView.layer.shadowPath.
    import UIKit
    
    @IBDesignable
    class ViewController: UIViewController {
    
        @IBOutlet weak var textField: UITextField!
        
        override func viewDidLoad() {
            super.viewDidLoad()
    
            textField.layer.shadowColor = UIColor.purple.cgColor
            textField.layer.cornerRadius = 8
    
            textField.layer.masksToBounds = false
            textField.layer.shadowOffset = CGSize.zero
            textField.layer.shadowRadius = 3.0
            textField.layer.shadowOpacity = 0.7
    
            let path = UIBezierPath()
            path.move(to: CGPoint(x: 0.0, y: 0.0))
            path.addLine(to: CGPoint(x: textField.bounds.size.width/2, y: textField.bounds.size.height/2))
            path.addLine(to: CGPoint(x: textField.bounds.maxX, y: 0.0))
            path.addLine(to: CGPoint(x: textField.bounds.maxX, y: textField.bounds.maxY))
            path.addLine(to: CGPoint(x: 0.0, y: textField.bounds.maxY))
            path.close()
            textField.layer.shadowPath = path.cgPath
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    }

    Вышло так:
    beVqPQ2jSguwZ8-Vva6S9w.jpg
    Путь использовал такой:
    VIBE4c0dTAuFQXiDfhoLPA.jpg
    Тебе остаётся для лучшего качества сделать скажем такой путь:
    WmsQS6asSLenTPqh9GKKRQ.jpg
    Или более извилистый путь, если ты хочешь уменьшить глубину тени слева и справа.
    Ответ написан
    Комментировать
  • Как вычислять производные в си?

    doublench21
    @doublench21
    Неужели совсем всё настолько печально? Определение производной в точке: (f(x0+Δx) - f(x0))/Δx, где Δx - чем меньше, тем точнее.
    Ответ написан
    Комментировать
  • Грамматика для языка Си?

    doublench21
    @doublench21
    Да как бы грамматика любого языка описывается в стандарте языка. Когда-то писал лексер языка Си. https://doublench.github.io
    Ответ написан
    Комментировать
  • Где писать desktop приложений на C++ под Windows?

    doublench21
    @doublench21
    Если хочешь писать быстро и качественно, то C++ тебе тут не поможет при всём моём уважении к QT. Ответ всегда супер очевидный, хочешь писать десктопные приложения(это очевидно только Windows/macOS), то писать нужно нативно. Под Windows это C#+WPF, под macOS это Swift. Оба эти языка позволяют с лёгкость(ну почти) перейти на другой род деятельности. Скажем с C#+WPF(делаем десктопные приложения), перейти в WebDev с тем же языком C#+что-то, перейти на написание игр под Unity(тоже C#), писать мобильные приложения под iOS/Android на Mono(тоже C#). Вообщем сами видите, что C# Вас ни в чём не ограничивает, плюс как язык он куда быстрее развивается нежели C++(да это не всегда говорит, что язык лучше, но всё же). История про Swift развивается таким же макаром, только там платформа macOS.

    А что C++? Куда Вы пойдете дальше, если Вам захочется делать что-то другое? На C++ пишут игры, может узко специализированные вещи, которые на данном этапе Вы конечно делать не будете.
    Ответ написан
    5 комментариев
  • 'subscript' is unavailable: cannot subscript String with an Int, see the documentation comment for discussion Swift 4?

    doublench21
    @doublench21 Куратор тега Swift
    Потому-что у строк нету привычного индекса типа Int. Связанно это с Unicode скалярами. Нужно делать как-то так:
    let greeting = "Guten Tag!"
    greeting[greeting.startIndex]
    // G
    greeting[greeting.index(before: greeting.endIndex)]
    // !
    greeting[greeting.index(after: greeting.startIndex)]
    // u
    let index = greeting.index(greeting.startIndex, offsetBy: 7)
    greeting[index]
    // a
    Ответ написан
    Комментировать
  • Как добавить заголовок в запросы внутри WKWebView?

    doublench21
    @doublench21 Куратор тега Swift
    There will not be any difference between loading web view from loadRequest vs loadHTMLString method, shouldStartLoadWithRequest method will be called in both cases. You can override your headers there and add header as per your requirements.
    Ответ написан
  • Как в ios слушать смену сети?

    doublench21
    @doublench21 Куратор тега Swift
    Слава богу в iOS такого делать нельзя!
    Вот здесь пишется, что можно делать в background:
    Declaring Your App’s Supported Background Tasks
    https://developer.apple.com/library/content/docume...
    Ответ написан
    Комментировать
  • Регулярные выражения в Swift?

    doublench21
    @doublench21 Куратор тега Swift
    Swift 4 Xcode 9.0
    import Foundation
    
    // Дополним String для простоты работы с NSRegularExpression
    extension String {
        // Вычислимое св-во, которое возвращает NSRange строки String
        var toNSRange: NSRange { return NSMakeRange(0, self.utf16.count) }
    
        // Метод возвращающий String по заданному NSRange
        func substringFromNSRange(with nsrange: NSRange) -> String? {
            guard let range = Range(nsrange) else { return nil }
            let start = String.UTF16Index(encodedOffset: range.lowerBound)
            let end = String.UTF16Index(encodedOffset: range.upperBound)
            return String(self.utf16[start..<end])
        }
    }
    
    var htmlContext = "products_and_categories(123123)]}"
    let regExp = try? NSRegularExpression(pattern: "products_and_categories(.*?)\\]\\}")
    let matches = regExp?.matches(in: htmlContext, range: htmlContext.toNSRange)
    for match in matches! {
        print(htmlContext.substringFromNSRange(with: match.range)!)
    }
    Ответ написан
    1 комментарий
  • Можно ли создать Telegram-бота, используя Swift, и разумно ли это?

    doublench21
    @doublench21 Куратор тега Swift
    Да, конечно можно! А о разумности, давай подумаем. Очевидно, после разработки этот код должен будет работать на каком-то Linux based сервере и вот тут могут возникнуть проблемы. Дело в том, что под Linix, основной фреймворк Swift - Foundation, ещё не полностью портирован. Отсюда могут возникнуть некоторые проблемы, в частности не полностью реализованный URLSession Class.

    P.S. Swift - это очень круто, но он очень молод и поэтому на сервера его пока рано ставить, в виду проблем указанных выше.
    P.P.S. Но для развития навыков Swift на macOS - да конечно, проблем в написании такого бота не возникнет. Welcome как говорится...
    Ответ написан
    Комментировать
  • XCode или CLion?

    doublench21
    @doublench21
    Конечно Xcode. Тут даже вопросов быть не должно. Не ставить же Clion на чёртовой джаве, который даже простой файл открыть в состоянии, лишь спустя несколько секунд.

    А вообще, что ты собрался писать на C++ под macOS? Под macOS нативно - это писать на obj-c/swift/си, ну никак не на c++. Ядро написано на СИ, а основные фреймворки - это в перемешку obj-c/swift. К тому же из них нельзя вызвать методы из C++, только Си.

    Хочешь писать под macOS, пиши на Swift, а самые критичные моменты дописывай на Си. Вот и всё.
    Ответ написан
    7 комментариев
  • Как искать посты в Facebook api?

    doublench21
    @doublench21
    Since v2.0 of the Graph API, Public Post search is no longer available: https://developers.facebook.com/docs/apps/changelo...
    Ответ написан
    Комментировать
  • NIL в красно-черном дереве?

    doublench21
    @doublench21 Автор вопроса
    Mercury13 , вообщем все и вправду было в этом NILL. Плюс я ни разу не использовал this, а видимо стоило, как я позже понял. Исходники:
    //
    //  rbtree.h
    //  rbtreee
    //
    //  Created by Lutfullin Ruslan on 23.04.15.
    //  Copyright (c) 2015 Ruslan Lutfullin. All rights reserved.
    //
    
    #ifndef __rbtreee__rbtree__
    #define __rbtreee__rbtree__
    
    #include <stdio.h>
    
    enum color { RED, BLACK };
    
    class Node {
    public:
      int data;
      color color;
      Node *left;
      Node *right;
      Node *parrent;
    
    public:
      Node(int data)
          : left(NULL), right(NULL), parrent(NULL), color(RED), data(data){};
    
      virtual ~Node(){};
    
    public:
      friend class RBtree;
    };
    
    class RBtree {
    public:
      Node *root;
      Node *NIL;
    
    public:
      RBtree();
      virtual ~RBtree();
    
    public:
      void tree_insert(Node *n);
      void left_rotate(Node *n);
      void right_rotate(Node *n);
      void rb_insert(Node *n);
      Node *rb_delete(Node *n);
      void rb_delete_fixup(Node *n);
      Node *tree_successor(Node *n);
      Node *tree_predecessor(Node *n);
      void inorder_tree_walk(Node *n);
      Node *iterative_tree_search(Node *n, int data);
      Node *tree_minimum(Node *n);
      Node *tree_maximum(Node *n);
    
      class Iterator {};
    };
    
    #endif /* defined(__rbtreee__rbtree__) */


    //
    //  rbtree.cpp
    //  rbtreee
    //
    //  Created by Lutfullin Ruslan on 23.04.15.
    //  Copyright (c) 2015 Ruslan Lutfullin. All rights reserved.
    //
    
    #include "rbtree.h"
    #include <iostream>
    
    RBtree::RBtree() {
      this->NIL = new Node(-1);
      this->NIL->color = BLACK;
      this->NIL->left = this->NIL->right = this->NIL->parrent = this->NIL;
    
      this->root = this->NIL;
      this->root->color = BLACK;
    }
    
    RBtree::~RBtree() { delete this->root; }
    
    void RBtree::inorder_tree_walk(Node *n) {
      if (n != this->NIL) {
        this->inorder_tree_walk(n->left);
        std::cout << n->data << " ";
        this->inorder_tree_walk(n->right);
      }
    }
    
    Node *RBtree::iterative_tree_search(Node *n, int data) {
      while (n != this->NIL && data != n->data) {
        if (data < n->data) {
          n = n->left;
        } else {
          n = n->right;
        }
      }
      return n;
    }
    
    Node *RBtree::tree_minimum(Node *n) {
      while (n->left != this->NIL) {
        n = n->left;
      }
      return n;
    }
    
    Node *RBtree::tree_maximum(Node *n) {
      while (n->right != this->NIL) {
        n = n->right;
      }
      return n;
    }
    
    Node *RBtree::tree_successor(Node *n) {
      if (n->right != this->NIL) {
        return this->tree_minimum(n->right);
      }
      Node *y = n->parrent;
      while (y != this->NIL && n == y->right) {
        n = y;
        y = y->parrent;
      }
      return y;
    }
    
    Node *RBtree::tree_predecessor(Node *n) {
      if (n->left != this->NIL) {
        return this->tree_minimum(n->left);
      }
      Node *y = n->parrent;
      while (y != this->NIL && n == y->left) {
        n = y;
        y = y->parrent;
      }
      return y;
    }
    
    void RBtree::tree_insert(Node *z) {
      Node *y = this->NIL, *x = this->root;
      while (x != this->NIL) {
        y = x;
        if (z->data < x->data)
          x = x->left;
        else
          x = x->right;
      }
      z->parrent = y;
      if (y == this->NIL) {
        this->root = z;
      } else {
        if (z->data < y->data) {
          y->left = z;
        } else {
          y->right = z;
        }
      }
    }
    
    void RBtree::left_rotate(Node *x) {
      Node *y;
      y = x->right;
      x->right = y->left;
      if (y->left != this->NIL) {
        y->left->parrent = x;
      }
      y->parrent = x->parrent;
      if (x->parrent == this->NIL) {
        this->root = y;
      } else {
        if (x == x->parrent->left) {
          x->parrent->left = y;
        } else {
          x->parrent->right = y;
        }
      }
      y->left = x;
      x->parrent = y;
    }
    
    void RBtree::right_rotate(Node *y) {
      Node *x;
      x = y->left;
      y->left = x->right;
      if (x->right != this->NIL) {
        x->right->parrent = y;
      }
      x->parrent = y->parrent;
      if (y->parrent == this->NIL) {
        this->root = x;
      } else {
        if (y == y->parrent->left) {
          y->parrent->left = x;
        } else {
          y->parrent->right= x;
        }
      }
      x->right = y;
      y->parrent = x;
    }
    
    void RBtree::rb_insert(Node *z) {
    
      this->tree_insert(z);
      Node *y;
      z->left = z->right = this->NIL;
      z->color = RED;
      while (z != this->root && z->parrent->color == RED) {
        if (z->parrent == z->parrent->parrent->left) {
          y = z->parrent->parrent->right;
          if (y->color == RED) {
            z->parrent->color = BLACK;
            y->color = BLACK;
            z->parrent->parrent->color = RED;
            z = z->parrent->parrent;
          } else {
            if (z == z->parrent->right) {
              z = z->parrent;
              this->left_rotate(z);
            }
            z->parrent->color = BLACK;
            z->parrent->parrent->color = RED;
            this->right_rotate(z->parrent->parrent);
          }
        } else {
          y = z->parrent->parrent->left;
          if (y->color == RED) {
            z->parrent->color = BLACK;
            y->color = BLACK;
            z->parrent->parrent->color = RED;
            z = z->parrent->parrent;
          } else {
            if (z == z->parrent->left) {
              z = z->parrent;
              this->right_rotate(z);
            }
            z->parrent->color = BLACK;
            z->parrent->parrent->color = RED;
            this->left_rotate(z->parrent->parrent);
          }
        }
      }
      this->root->color = BLACK;
    }
    
    Node *RBtree::rb_delete(Node *z) {
      Node *x, *y;
      if (z->left == this->NIL || z->right == this->NIL) {
        y = z;
      } else {
        y = this->tree_successor(z);
      }
      if (y->left != this->NIL) {
        x = y->left;
      } else {
        x = y->right;
      }
      x->parrent = y->parrent;
      if (y->parrent == this->NIL) {
        this->root = x;
      } else {
        if (y == y->parrent->left) {
          y->parrent->left = x;
        } else {
          y->parrent->right = x;
        }
      }
      if (y != z) {
        z->data = y->data;
      }
      if (y->color == BLACK) {
        this->rb_delete_fixup(x);
      }
      return y;
    }
    
    void RBtree::rb_delete_fixup(Node *x) {
      Node *w;
      while (x != this->root && x->color == BLACK) {
        if (x == x->parrent->left) {
          w = x->parrent->right;
          if (w->color == RED) {
            w->color = BLACK;
            x->parrent->color = RED;
            this->left_rotate(x->parrent);
            w = x->parrent->right;
          }
          if (w->left->color == BLACK && w->right->color == BLACK) {
            w->color = RED;
            x = x->parrent;
          } else {
            if (w->right->color == BLACK) {
              w->left->color = BLACK;
              w->color = RED;
              this->right_rotate(w);
              w = x->parrent->right;
            }
            w->color = x->parrent->color;
            x->parrent->color = BLACK;
            w->right->color = BLACK;
            this->left_rotate(x->parrent);
            x = this->root;
          }
        } else {
          w = x->parrent->left;
          if (w->color == RED) {
            w->color = BLACK;
            x->parrent->color = RED;
            this->left_rotate(x->parrent);
            w = x->parrent->left;
          }
          if (w->right->color == BLACK && w->left->color == BLACK) {
            w->color = RED;
            x = x->parrent;
          } else {
            if (w->left->color == BLACK) {
              w->right->color = BLACK;
              w->color = RED;
              this->right_rotate(w);
              w = x->parrent->left;
            }
            w->color = x->parrent->color;
            x->parrent->color = BLACK;
            w->left->color = BLACK;
            this->left_rotate(x->parrent);
            x = this->root;
          }
        }
      }
      x->color = BLACK;
    }
    Ответ написан