Как Вы добавляете многострочный текст к UIButton?

Вы, похоже, ищете условную агрегацию:

SELECT 
    count(*) total,
    SUM(CASE WHEN score BETWEEN 0.1 AND 0.3  THEN 1 ELSE 0 END) low,
    SUM(CASE WHEN score BETWEEN 0.3 AND 0.6  THEN 1 ELSE 0 END) medium,
    SUM(CASE WHEN score BETWEEN 0.6 AND 0.95 THEN 1 ELSE 0 END) high,
    SUM(CASE WHEN score >= 0.95 THEN 1 ELSE 0 END) 'very_high'
FROM my_table

Этот запрос вернет одну строку, показывающую общее количество проанализированных строк и количество строк, принадлежащих каждой категории. col BETWEEN val1 AND val2 является сокращением для col >= val1 AND col < val2.

356
задан Erik Godard 5 August 2017 в 10:19
поделиться

7 ответов

Думаю, у меня есть рабочее решение. Спасибо всем за то, что указали мне правильное направление (я надеюсь).

Сборки не могут быть выгружены напрямую, но AppDomain могут. Я создал вспомогательную библиотеку, которая загружается в новый домен приложения и может скомпилировать новую сборку из кода. Вот как выглядит класс в этой вспомогательной библиотеке:

public class CompilerRunner : MarshalByRefObject
{
    private Assembly assembly = null;

    public void PrintDomain()
    {
        Console.WriteLine("Object is executing in AppDomain \"{0}\"",
            AppDomain.CurrentDomain.FriendlyName);
    }

    public bool Compile(string code)
    {
        CSharpCodeProvider codeProvider = new CSharpCodeProvider();
        CompilerParameters parameters = new CompilerParameters();
        parameters.GenerateInMemory = true;
        parameters.GenerateExecutable = false;
        parameters.ReferencedAssemblies.Add("system.dll");

        CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, code);
        if (!results.Errors.HasErrors)
        {
            this.assembly = results.CompiledAssembly;
        }
        else
        {
            this.assembly = null;
        }

        return this.assembly != null;
    }

    public object Run(string typeName, string methodName, object[] args)
    {
        Type type = this.assembly.GetType(typeName);
        return type.InvokeMember(methodName, BindingFlags.InvokeMethod, null, assembly, args);
    }

}

Он очень простой, но его было достаточно для тестирования. PrintDomain нужен, чтобы убедиться, что он действительно живет в моем новом домене приложений. Компиляция берет некоторый исходный код и пытается создать сборку. Run позволяет нам тестировать выполнение статических методов из данного исходного кода.

Вот как я использую вспомогательную библиотеку:

static void CreateCompileAndRun()
{
    AppDomain domain = AppDomain.CreateDomain("MyDomain");

    CompilerRunner cr = (CompilerRunner)domain.CreateInstanceFromAndUnwrap("CompilerRunner.dll", "AppDomainCompiler.CompilerRunner");            
    cr.Compile("public class Hello { public static string Say() { return \"hello\"; } }");            
    string result = (string)cr.Run("Hello", "Say", new object[0]);

    AppDomain.Unload(domain);
}

Она в основном создает домен, создает экземпляр моего вспомогательного класса (CompilerRunner), использует его для компиляции нового сборка (скрытая), запускает некоторый код из этой новой сборки, а затем выгружает домен, чтобы освободить память.

Вы заметите использование MarshalByRefObject и CreateInstanceFromAndUnwrap. Это важно для обеспечения того, чтобы вспомогательная библиотека действительно существовала в новом домене.

Если кто-то заметит какие-либо проблемы или у вас есть предложения по их улучшению, я хотел бы их услышать.

663
ответ дан 23 November 2019 в 00:21
поделиться

Хотя это должно хорошо добавить подпредставление к управлению, нет никакой гарантии, это будет на самом деле работать, потому что управление не могло бы ожидать, что это будет там, и могло бы таким образом вести себя плохо. Если можно выйти сухим из воды, просто добавьте маркировку как одноуровневое представление кнопки и установите ее кадр так, чтобы это перекрыло кнопку; пока это установлено появиться сверху кнопки, ничто, что кнопка может сделать, затенит его.

, Другими словами:

[button.superview addSubview:myLabel];
myLabel.center = button.center;
-4
ответ дан Brent Royal-Gordon 23 November 2019 в 00:21
поделиться

Класс кнопки самокрутки. Это - безусловно лучшее решение в конечном счете. UIButton и другие классы UIKit очень строги в том, как можно настроить их.

0
ответ дан 23 November 2019 в 00:21
поделиться

Относительно идеи Брента поместить заголовок UILabel как одноуровневое представление, это не кажется мне как очень хорошая идея. Я продолжаю думать в проблемах взаимодействия с должным UILabel к его сенсорным событиям, не проходящим через представление UIBUTTON.

, С другой стороны, с UILabel как подпредставление UIButton, я - довольно удобное знание, что сенсорные события будут всегда распространяться к суперпредставлению UILABEL.

я проявлял этот подход и не заметил, что любая из проблем сообщила с backgroundImage. Я добавил этот код в-titleRectForContentRect: из подкласса UIButton, но кода может также быть помещен в рисование стандартной программы суперпредставления UIButton, которое в этом случае необходимо заменить все ссылки на сам с переменной UIBUTTON.

#define TITLE_LABEL_TAG 1234

- (CGRect)titleRectForContentRect:(CGRect)rect
{   
    // define the desired title inset margins based on the whole rect and its padding
    UIEdgeInsets padding = [self titleEdgeInsets];
    CGRect titleRect = CGRectMake(rect.origin.x    + padding.left, 
                                  rect.origin.x    + padding.top, 
                                  rect.size.width  - (padding.right + padding.left), 
                                  rect.size.height - (padding.bottom + padding].top));

    // save the current title view appearance
    NSString *title = [self currentTitle];
    UIColor  *titleColor = [self currentTitleColor];
    UIColor  *titleShadowColor = [self currentTitleShadowColor];

    // we only want to add our custom label once; only 1st pass shall return nil
    UILabel  *titleLabel = (UILabel*)[self viewWithTag:TITLE_LABEL_TAG];


    if (!titleLabel) 
    {
        // no custom label found (1st pass), we will be creating & adding it as subview
        titleLabel = [[UILabel alloc] initWithFrame:titleRect];
        [titleLabel setTag:TITLE_LABEL_TAG];

        // make it multi-line
        [titleLabel setNumberOfLines:0];
        [titleLabel setLineBreakMode:UILineBreakModeWordWrap];

        // title appearance setup; be at will to modify
        [titleLabel setBackgroundColor:[UIColor clearColor]];
        [titleLabel setFont:[self font]];
        [titleLabel setShadowOffset:CGSizeMake(0, 1)];
        [titleLabel setTextAlignment:UITextAlignmentCenter];

        [self addSubview:titleLabel];
        [titleLabel release];
    }

    // finally, put our label in original title view's state
    [titleLabel setText:title];
    [titleLabel setTextColor:titleColor];
    [titleLabel setShadowColor:titleShadowColor];

    // and return empty rect so that the original title view is hidden
    return CGRectZero;
}

я действительно не торопился и записал немного больше об этом здесь . Там, я также указываю на более короткое решение, хотя оно не делает довольно пригодный все сценарии и включает некоторое частное взламывание представлений. Также там, можно загрузить подкласс UIButton, готовый использоваться.

3
ответ дан jpedroso 23 November 2019 в 00:21
поделиться

В первую очередь, необходимо знать, что UIButton уже имеет UILabel в нем. Можно установить его с помощью –setTitle:forState:.

проблема с Вашим примером состоит в том, что необходимо установить UILabel's numberOfLines свойство к чему-то другому, чем его значение по умолчанию 1. Необходимо также рассмотреть lineBreakMode свойство.

7
ответ дан Rog 23 November 2019 в 00:21
поделиться

Быстро 5, Для многострочного текста в UIButton

  let button = UIButton()
  button.titleLabel?.lineBreakMode = .byWordWrapping
  button.titleLabel?.textAlignment = .center
  button.titleLabel?.numberOfLines = 0 // for Multi line text
2
ответ дан 23 November 2019 в 00:21
поделиться

There is a much easier way:

someButton.lineBreakMode = UILineBreakModeWordWrap;

(Edit for iOS 3 and later:)

someButton.titleLabel.lineBreakMode = UILineBreakModeWordWrap;
11
ответ дан 23 November 2019 в 00:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: